OSDN Git Service

* target-def.h (TARGET_HAVE_NAMED_SECTIONS): Move to
[pf3gnuchains/gcc-fork.git] / gcc / except.c
1 /* Implements exception handling.
2    Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3    1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
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 "thrown" from within a
25    function.  This event can then be "caught" by the callers of
26    the function.
27
28    The representation of exceptions changes several times during
29    the compilation process:
30
31    In the beginning, in the front end, we have the GENERIC trees
32    TRY_CATCH_EXPR, TRY_FINALLY_EXPR, WITH_CLEANUP_EXPR,
33    CLEANUP_POINT_EXPR, CATCH_EXPR, and EH_FILTER_EXPR.
34
35    During initial gimplification (gimplify.c) these are lowered
36    to the GIMPLE_TRY, GIMPLE_CATCH, and GIMPLE_EH_FILTER nodes.
37    The WITH_CLEANUP_EXPR and CLEANUP_POINT_EXPR nodes are converted
38    into GIMPLE_TRY_FINALLY nodes; the others are a more direct 1-1
39    conversion.
40
41    During pass_lower_eh (tree-eh.c) we record the nested structure
42    of the TRY nodes in EH_REGION nodes in CFUN->EH->REGION_TREE.
43    We expand the eh_protect_cleanup_actions langhook into MUST_NOT_THROW
44    regions at this time.  We can then flatten the statements within
45    the TRY nodes to straight-line code.  Statements that had been within
46    TRY nodes that can throw are recorded within CFUN->EH->THROW_STMT_TABLE,
47    so that we may remember what action is supposed to be taken if
48    a given statement does throw.  During this lowering process,
49    we create an EH_LANDING_PAD node for each EH_REGION that has
50    some code within the function that needs to be executed if a
51    throw does happen.  We also create RESX statements that are
52    used to transfer control from an inner EH_REGION to an outer
53    EH_REGION.  We also create EH_DISPATCH statements as placeholders
54    for a runtime type comparison that should be made in order to
55    select the action to perform among different CATCH and EH_FILTER
56    regions.
57
58    During pass_lower_eh_dispatch (tree-eh.c), which is run after
59    all inlining is complete, we are able to run assign_filter_values,
60    which allows us to map the set of types manipulated by all of the
61    CATCH and EH_FILTER regions to a set of integers.  This set of integers
62    will be how the exception runtime communicates with the code generated
63    within the function.  We then expand the GIMPLE_EH_DISPATCH statements
64    to a switch or conditional branches that use the argument provided by
65    the runtime (__builtin_eh_filter) and the set of integers we computed
66    in assign_filter_values.
67
68    During pass_lower_resx (tree-eh.c), which is run near the end
69    of optimization, we expand RESX statements.  If the eh region
70    that is outer to the RESX statement is a MUST_NOT_THROW, then
71    the RESX expands to some form of abort statement.  If the eh
72    region that is outer to the RESX statement is within the current
73    function, then the RESX expands to a bookkeeping call
74    (__builtin_eh_copy_values) and a goto.  Otherwise, the next
75    handler for the exception must be within a function somewhere
76    up the call chain, so we call back into the exception runtime
77    (__builtin_unwind_resume).
78
79    During pass_expand (cfgexpand.c), we generate REG_EH_REGION notes
80    that create an rtl to eh_region mapping that corresponds to the
81    gimple to eh_region mapping that had been recorded in the
82    THROW_STMT_TABLE.
83
84    During pass_rtl_eh (except.c), we generate the real landing pads
85    to which the runtime will actually transfer control.  These new
86    landing pads perform whatever bookkeeping is needed by the target
87    backend in order to resume execution within the current function.
88    Each of these new landing pads falls through into the post_landing_pad
89    label which had been used within the CFG up to this point.  All
90    exception edges within the CFG are redirected to the new landing pads.
91    If the target uses setjmp to implement exceptions, the various extra
92    calls into the runtime to register and unregister the current stack
93    frame are emitted at this time.
94
95    During pass_convert_to_eh_region_ranges (except.c), we transform
96    the REG_EH_REGION notes attached to individual insns into
97    non-overlapping ranges of insns bounded by NOTE_INSN_EH_REGION_BEG
98    and NOTE_INSN_EH_REGION_END.  Each insn within such ranges has the
99    same associated action within the exception region tree, meaning
100    that (1) the exception is caught by the same landing pad within the
101    current function, (2) the exception is blocked by the runtime with
102    a MUST_NOT_THROW region, or (3) the exception is not handled at all
103    within the current function.
104
105    Finally, during assembly generation, we call
106    output_function_exception_table (except.c) to emit the tables with
107    which the exception runtime can determine if a given stack frame
108    handles a given exception, and if so what filter value to provide
109    to the function when the non-local control transfer is effected.
110    If the target uses dwarf2 unwinding to implement exceptions, then
111    output_call_frame_info (dwarf2out.c) emits the required unwind data.  */
112
113
114 #include "config.h"
115 #include "system.h"
116 #include "coretypes.h"
117 #include "tm.h"
118 #include "rtl.h"
119 #include "tree.h"
120 #include "flags.h"
121 #include "function.h"
122 #include "expr.h"
123 #include "libfuncs.h"
124 #include "insn-config.h"
125 #include "except.h"
126 #include "integrate.h"
127 #include "hard-reg-set.h"
128 #include "basic-block.h"
129 #include "output.h"
130 #include "dwarf2asm.h"
131 #include "dwarf2out.h"
132 #include "dwarf2.h"
133 #include "toplev.h"
134 #include "hashtab.h"
135 #include "intl.h"
136 #include "ggc.h"
137 #include "tm_p.h"
138 #include "target.h"
139 #include "common/common-target.h"
140 #include "langhooks.h"
141 #include "cgraph.h"
142 #include "diagnostic.h"
143 #include "tree-pretty-print.h"
144 #include "tree-pass.h"
145 #include "timevar.h"
146 #include "tree-flow.h"
147
148 /* Provide defaults for stuff that may not be defined when using
149    sjlj exceptions.  */
150 #ifndef EH_RETURN_DATA_REGNO
151 #define EH_RETURN_DATA_REGNO(N) INVALID_REGNUM
152 #endif
153
154 static GTY(()) int call_site_base;
155 static GTY ((param_is (union tree_node)))
156   htab_t type_to_runtime_map;
157
158 /* Describe the SjLj_Function_Context structure.  */
159 static GTY(()) tree sjlj_fc_type_node;
160 static int sjlj_fc_call_site_ofs;
161 static int sjlj_fc_data_ofs;
162 static int sjlj_fc_personality_ofs;
163 static int sjlj_fc_lsda_ofs;
164 static int sjlj_fc_jbuf_ofs;
165 \f
166
167 struct GTY(()) call_site_record_d
168 {
169   rtx landing_pad;
170   int action;
171 };
172 \f
173 static bool get_eh_region_and_lp_from_rtx (const_rtx, eh_region *,
174                                            eh_landing_pad *);
175
176 static int t2r_eq (const void *, const void *);
177 static hashval_t t2r_hash (const void *);
178
179 static int ttypes_filter_eq (const void *, const void *);
180 static hashval_t ttypes_filter_hash (const void *);
181 static int ehspec_filter_eq (const void *, const void *);
182 static hashval_t ehspec_filter_hash (const void *);
183 static int add_ttypes_entry (htab_t, tree);
184 static int add_ehspec_entry (htab_t, htab_t, tree);
185 static void dw2_build_landing_pads (void);
186
187 static int action_record_eq (const void *, const void *);
188 static hashval_t action_record_hash (const void *);
189 static int add_action_record (htab_t, int, int);
190 static int collect_one_action_chain (htab_t, eh_region);
191 static int add_call_site (rtx, int, int);
192
193 static void push_uleb128 (VEC (uchar, gc) **, unsigned int);
194 static void push_sleb128 (VEC (uchar, gc) **, int);
195 #ifndef HAVE_AS_LEB128
196 static int dw2_size_of_call_site_table (int);
197 static int sjlj_size_of_call_site_table (void);
198 #endif
199 static void dw2_output_call_site_table (int, int);
200 static void sjlj_output_call_site_table (void);
201
202 \f
203 void
204 init_eh (void)
205 {
206   if (! flag_exceptions)
207     return;
208
209   type_to_runtime_map = htab_create_ggc (31, t2r_hash, t2r_eq, NULL);
210
211   /* Create the SjLj_Function_Context structure.  This should match
212      the definition in unwind-sjlj.c.  */
213   if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ)
214     {
215       tree f_jbuf, f_per, f_lsda, f_prev, f_cs, f_data, tmp;
216
217       sjlj_fc_type_node = lang_hooks.types.make_type (RECORD_TYPE);
218
219       f_prev = build_decl (BUILTINS_LOCATION,
220                            FIELD_DECL, get_identifier ("__prev"),
221                            build_pointer_type (sjlj_fc_type_node));
222       DECL_FIELD_CONTEXT (f_prev) = sjlj_fc_type_node;
223
224       f_cs = build_decl (BUILTINS_LOCATION,
225                          FIELD_DECL, get_identifier ("__call_site"),
226                          integer_type_node);
227       DECL_FIELD_CONTEXT (f_cs) = sjlj_fc_type_node;
228
229       tmp = build_index_type (size_int (4 - 1));
230       tmp = build_array_type (lang_hooks.types.type_for_mode
231                                 (targetm.unwind_word_mode (), 1),
232                               tmp);
233       f_data = build_decl (BUILTINS_LOCATION,
234                            FIELD_DECL, get_identifier ("__data"), tmp);
235       DECL_FIELD_CONTEXT (f_data) = sjlj_fc_type_node;
236
237       f_per = build_decl (BUILTINS_LOCATION,
238                           FIELD_DECL, get_identifier ("__personality"),
239                           ptr_type_node);
240       DECL_FIELD_CONTEXT (f_per) = sjlj_fc_type_node;
241
242       f_lsda = build_decl (BUILTINS_LOCATION,
243                            FIELD_DECL, get_identifier ("__lsda"),
244                            ptr_type_node);
245       DECL_FIELD_CONTEXT (f_lsda) = sjlj_fc_type_node;
246
247 #ifdef DONT_USE_BUILTIN_SETJMP
248 #ifdef JMP_BUF_SIZE
249       tmp = size_int (JMP_BUF_SIZE - 1);
250 #else
251       /* Should be large enough for most systems, if it is not,
252          JMP_BUF_SIZE should be defined with the proper value.  It will
253          also tend to be larger than necessary for most systems, a more
254          optimal port will define JMP_BUF_SIZE.  */
255       tmp = size_int (FIRST_PSEUDO_REGISTER + 2 - 1);
256 #endif
257 #else
258       /* builtin_setjmp takes a pointer to 5 words.  */
259       tmp = size_int (5 * BITS_PER_WORD / POINTER_SIZE - 1);
260 #endif
261       tmp = build_index_type (tmp);
262       tmp = build_array_type (ptr_type_node, tmp);
263       f_jbuf = build_decl (BUILTINS_LOCATION,
264                            FIELD_DECL, get_identifier ("__jbuf"), tmp);
265 #ifdef DONT_USE_BUILTIN_SETJMP
266       /* We don't know what the alignment requirements of the
267          runtime's jmp_buf has.  Overestimate.  */
268       DECL_ALIGN (f_jbuf) = BIGGEST_ALIGNMENT;
269       DECL_USER_ALIGN (f_jbuf) = 1;
270 #endif
271       DECL_FIELD_CONTEXT (f_jbuf) = sjlj_fc_type_node;
272
273       TYPE_FIELDS (sjlj_fc_type_node) = f_prev;
274       TREE_CHAIN (f_prev) = f_cs;
275       TREE_CHAIN (f_cs) = f_data;
276       TREE_CHAIN (f_data) = f_per;
277       TREE_CHAIN (f_per) = f_lsda;
278       TREE_CHAIN (f_lsda) = f_jbuf;
279
280       layout_type (sjlj_fc_type_node);
281
282       /* Cache the interesting field offsets so that we have
283          easy access from rtl.  */
284       sjlj_fc_call_site_ofs
285         = (tree_low_cst (DECL_FIELD_OFFSET (f_cs), 1)
286            + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_cs), 1) / BITS_PER_UNIT);
287       sjlj_fc_data_ofs
288         = (tree_low_cst (DECL_FIELD_OFFSET (f_data), 1)
289            + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_data), 1) / BITS_PER_UNIT);
290       sjlj_fc_personality_ofs
291         = (tree_low_cst (DECL_FIELD_OFFSET (f_per), 1)
292            + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_per), 1) / BITS_PER_UNIT);
293       sjlj_fc_lsda_ofs
294         = (tree_low_cst (DECL_FIELD_OFFSET (f_lsda), 1)
295            + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_lsda), 1) / BITS_PER_UNIT);
296       sjlj_fc_jbuf_ofs
297         = (tree_low_cst (DECL_FIELD_OFFSET (f_jbuf), 1)
298            + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_jbuf), 1) / BITS_PER_UNIT);
299     }
300 }
301
302 void
303 init_eh_for_function (void)
304 {
305   cfun->eh = ggc_alloc_cleared_eh_status ();
306
307   /* Make sure zero'th entries are used.  */
308   VEC_safe_push (eh_region, gc, cfun->eh->region_array, NULL);
309   VEC_safe_push (eh_landing_pad, gc, cfun->eh->lp_array, NULL);
310 }
311 \f
312 /* Routines to generate the exception tree somewhat directly.
313    These are used from tree-eh.c when processing exception related
314    nodes during tree optimization.  */
315
316 static eh_region
317 gen_eh_region (enum eh_region_type type, eh_region outer)
318 {
319   eh_region new_eh;
320
321   /* Insert a new blank region as a leaf in the tree.  */
322   new_eh = ggc_alloc_cleared_eh_region_d ();
323   new_eh->type = type;
324   new_eh->outer = outer;
325   if (outer)
326     {
327       new_eh->next_peer = outer->inner;
328       outer->inner = new_eh;
329     }
330   else
331     {
332       new_eh->next_peer = cfun->eh->region_tree;
333       cfun->eh->region_tree = new_eh;
334     }
335
336   new_eh->index = VEC_length (eh_region, cfun->eh->region_array);
337   VEC_safe_push (eh_region, gc, cfun->eh->region_array, new_eh);
338
339   /* Copy the language's notion of whether to use __cxa_end_cleanup.  */
340   if (targetm.arm_eabi_unwinder && lang_hooks.eh_use_cxa_end_cleanup)
341     new_eh->use_cxa_end_cleanup = true;
342
343   return new_eh;
344 }
345
346 eh_region
347 gen_eh_region_cleanup (eh_region outer)
348 {
349   return gen_eh_region (ERT_CLEANUP, outer);
350 }
351
352 eh_region
353 gen_eh_region_try (eh_region outer)
354 {
355   return gen_eh_region (ERT_TRY, outer);
356 }
357
358 eh_catch
359 gen_eh_region_catch (eh_region t, tree type_or_list)
360 {
361   eh_catch c, l;
362   tree type_list, type_node;
363
364   gcc_assert (t->type == ERT_TRY);
365
366   /* Ensure to always end up with a type list to normalize further
367      processing, then register each type against the runtime types map.  */
368   type_list = type_or_list;
369   if (type_or_list)
370     {
371       if (TREE_CODE (type_or_list) != TREE_LIST)
372         type_list = tree_cons (NULL_TREE, type_or_list, NULL_TREE);
373
374       type_node = type_list;
375       for (; type_node; type_node = TREE_CHAIN (type_node))
376         add_type_for_runtime (TREE_VALUE (type_node));
377     }
378
379   c = ggc_alloc_cleared_eh_catch_d ();
380   c->type_list = type_list;
381   l = t->u.eh_try.last_catch;
382   c->prev_catch = l;
383   if (l)
384     l->next_catch = c;
385   else
386     t->u.eh_try.first_catch = c;
387   t->u.eh_try.last_catch = c;
388
389   return c;
390 }
391
392 eh_region
393 gen_eh_region_allowed (eh_region outer, tree allowed)
394 {
395   eh_region region = gen_eh_region (ERT_ALLOWED_EXCEPTIONS, outer);
396   region->u.allowed.type_list = allowed;
397
398   for (; allowed ; allowed = TREE_CHAIN (allowed))
399     add_type_for_runtime (TREE_VALUE (allowed));
400
401   return region;
402 }
403
404 eh_region
405 gen_eh_region_must_not_throw (eh_region outer)
406 {
407   return gen_eh_region (ERT_MUST_NOT_THROW, outer);
408 }
409
410 eh_landing_pad
411 gen_eh_landing_pad (eh_region region)
412 {
413   eh_landing_pad lp = ggc_alloc_cleared_eh_landing_pad_d ();
414
415   lp->next_lp = region->landing_pads;
416   lp->region = region;
417   lp->index = VEC_length (eh_landing_pad, cfun->eh->lp_array);
418   region->landing_pads = lp;
419
420   VEC_safe_push (eh_landing_pad, gc, cfun->eh->lp_array, lp);
421
422   return lp;
423 }
424
425 eh_region
426 get_eh_region_from_number_fn (struct function *ifun, int i)
427 {
428   return VEC_index (eh_region, ifun->eh->region_array, i);
429 }
430
431 eh_region
432 get_eh_region_from_number (int i)
433 {
434   return get_eh_region_from_number_fn (cfun, i);
435 }
436
437 eh_landing_pad
438 get_eh_landing_pad_from_number_fn (struct function *ifun, int i)
439 {
440   return VEC_index (eh_landing_pad, ifun->eh->lp_array, i);
441 }
442
443 eh_landing_pad
444 get_eh_landing_pad_from_number (int i)
445 {
446   return get_eh_landing_pad_from_number_fn (cfun, i);
447 }
448
449 eh_region
450 get_eh_region_from_lp_number_fn (struct function *ifun, int i)
451 {
452   if (i < 0)
453     return VEC_index (eh_region, ifun->eh->region_array, -i);
454   else if (i == 0)
455     return NULL;
456   else
457     {
458       eh_landing_pad lp;
459       lp = VEC_index (eh_landing_pad, ifun->eh->lp_array, i);
460       return lp->region;
461     }
462 }
463
464 eh_region
465 get_eh_region_from_lp_number (int i)
466 {
467   return get_eh_region_from_lp_number_fn (cfun, i);
468 }
469 \f
470 /* Returns true if the current function has exception handling regions.  */
471
472 bool
473 current_function_has_exception_handlers (void)
474 {
475   return cfun->eh->region_tree != NULL;
476 }
477 \f
478 /* A subroutine of duplicate_eh_regions.  Copy the eh_region tree at OLD.
479    Root it at OUTER, and apply LP_OFFSET to the lp numbers.  */
480
481 struct duplicate_eh_regions_data
482 {
483   duplicate_eh_regions_map label_map;
484   void *label_map_data;
485   struct pointer_map_t *eh_map;
486 };
487
488 static void
489 duplicate_eh_regions_1 (struct duplicate_eh_regions_data *data,
490                         eh_region old_r, eh_region outer)
491 {
492   eh_landing_pad old_lp, new_lp;
493   eh_region new_r;
494   void **slot;
495
496   new_r = gen_eh_region (old_r->type, outer);
497   slot = pointer_map_insert (data->eh_map, (void *)old_r);
498   gcc_assert (*slot == NULL);
499   *slot = (void *)new_r;
500
501   switch (old_r->type)
502     {
503     case ERT_CLEANUP:
504       break;
505
506     case ERT_TRY:
507       {
508         eh_catch oc, nc;
509         for (oc = old_r->u.eh_try.first_catch; oc ; oc = oc->next_catch)
510           {
511             /* We should be doing all our region duplication before and
512                during inlining, which is before filter lists are created.  */
513             gcc_assert (oc->filter_list == NULL);
514             nc = gen_eh_region_catch (new_r, oc->type_list);
515             nc->label = data->label_map (oc->label, data->label_map_data);
516           }
517       }
518       break;
519
520     case ERT_ALLOWED_EXCEPTIONS:
521       new_r->u.allowed.type_list = old_r->u.allowed.type_list;
522       if (old_r->u.allowed.label)
523         new_r->u.allowed.label
524             = data->label_map (old_r->u.allowed.label, data->label_map_data);
525       else
526         new_r->u.allowed.label = NULL_TREE;
527       break;
528
529     case ERT_MUST_NOT_THROW:
530       new_r->u.must_not_throw = old_r->u.must_not_throw;
531       break;
532     }
533
534   for (old_lp = old_r->landing_pads; old_lp ; old_lp = old_lp->next_lp)
535     {
536       /* Don't bother copying unused landing pads.  */
537       if (old_lp->post_landing_pad == NULL)
538         continue;
539
540       new_lp = gen_eh_landing_pad (new_r);
541       slot = pointer_map_insert (data->eh_map, (void *)old_lp);
542       gcc_assert (*slot == NULL);
543       *slot = (void *)new_lp;
544
545       new_lp->post_landing_pad
546         = data->label_map (old_lp->post_landing_pad, data->label_map_data);
547       EH_LANDING_PAD_NR (new_lp->post_landing_pad) = new_lp->index;
548     }
549
550   /* Make sure to preserve the original use of __cxa_end_cleanup.  */
551   new_r->use_cxa_end_cleanup = old_r->use_cxa_end_cleanup;
552
553   for (old_r = old_r->inner; old_r ; old_r = old_r->next_peer)
554     duplicate_eh_regions_1 (data, old_r, new_r);
555 }
556
557 /* Duplicate the EH regions from IFUN rooted at COPY_REGION into
558    the current function and root the tree below OUTER_REGION.
559    The special case of COPY_REGION of NULL means all regions.
560    Remap labels using MAP/MAP_DATA callback.  Return a pointer map
561    that allows the caller to remap uses of both EH regions and
562    EH landing pads.  */
563
564 struct pointer_map_t *
565 duplicate_eh_regions (struct function *ifun,
566                       eh_region copy_region, int outer_lp,
567                       duplicate_eh_regions_map map, void *map_data)
568 {
569   struct duplicate_eh_regions_data data;
570   eh_region outer_region;
571
572 #ifdef ENABLE_CHECKING
573   verify_eh_tree (ifun);
574 #endif
575
576   data.label_map = map;
577   data.label_map_data = map_data;
578   data.eh_map = pointer_map_create ();
579
580   outer_region = get_eh_region_from_lp_number (outer_lp);
581
582   /* Copy all the regions in the subtree.  */
583   if (copy_region)
584     duplicate_eh_regions_1 (&data, copy_region, outer_region);
585   else
586     {
587       eh_region r;
588       for (r = ifun->eh->region_tree; r ; r = r->next_peer)
589         duplicate_eh_regions_1 (&data, r, outer_region);
590     }
591
592 #ifdef ENABLE_CHECKING
593   verify_eh_tree (cfun);
594 #endif
595
596   return data.eh_map;
597 }
598
599 /* Return the region that is outer to both REGION_A and REGION_B in IFUN.  */
600
601 eh_region
602 eh_region_outermost (struct function *ifun, eh_region region_a,
603                      eh_region region_b)
604 {
605   sbitmap b_outer;
606
607   gcc_assert (ifun->eh->region_array);
608   gcc_assert (ifun->eh->region_tree);
609
610   b_outer = sbitmap_alloc (VEC_length (eh_region, ifun->eh->region_array));
611   sbitmap_zero (b_outer);
612
613   do
614     {
615       SET_BIT (b_outer, region_b->index);
616       region_b = region_b->outer;
617     }
618   while (region_b);
619
620   do
621     {
622       if (TEST_BIT (b_outer, region_a->index))
623         break;
624       region_a = region_a->outer;
625     }
626   while (region_a);
627
628   sbitmap_free (b_outer);
629   return region_a;
630 }
631 \f
632 static int
633 t2r_eq (const void *pentry, const void *pdata)
634 {
635   const_tree const entry = (const_tree) pentry;
636   const_tree const data = (const_tree) pdata;
637
638   return TREE_PURPOSE (entry) == data;
639 }
640
641 static hashval_t
642 t2r_hash (const void *pentry)
643 {
644   const_tree const entry = (const_tree) pentry;
645   return TREE_HASH (TREE_PURPOSE (entry));
646 }
647
648 void
649 add_type_for_runtime (tree type)
650 {
651   tree *slot;
652
653   /* If TYPE is NOP_EXPR, it means that it already is a runtime type.  */
654   if (TREE_CODE (type) == NOP_EXPR)
655     return;
656
657   slot = (tree *) htab_find_slot_with_hash (type_to_runtime_map, type,
658                                             TREE_HASH (type), INSERT);
659   if (*slot == NULL)
660     {
661       tree runtime = lang_hooks.eh_runtime_type (type);
662       *slot = tree_cons (type, runtime, NULL_TREE);
663     }
664 }
665
666 tree
667 lookup_type_for_runtime (tree type)
668 {
669   tree *slot;
670
671   /* If TYPE is NOP_EXPR, it means that it already is a runtime type.  */
672   if (TREE_CODE (type) == NOP_EXPR)
673     return type;
674
675   slot = (tree *) htab_find_slot_with_hash (type_to_runtime_map, type,
676                                             TREE_HASH (type), NO_INSERT);
677
678   /* We should have always inserted the data earlier.  */
679   return TREE_VALUE (*slot);
680 }
681
682 \f
683 /* Represent an entry in @TTypes for either catch actions
684    or exception filter actions.  */
685 struct ttypes_filter {
686   tree t;
687   int filter;
688 };
689
690 /* Compare ENTRY (a ttypes_filter entry in the hash table) with DATA
691    (a tree) for a @TTypes type node we are thinking about adding.  */
692
693 static int
694 ttypes_filter_eq (const void *pentry, const void *pdata)
695 {
696   const struct ttypes_filter *const entry
697     = (const struct ttypes_filter *) pentry;
698   const_tree const data = (const_tree) pdata;
699
700   return entry->t == data;
701 }
702
703 static hashval_t
704 ttypes_filter_hash (const void *pentry)
705 {
706   const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
707   return TREE_HASH (entry->t);
708 }
709
710 /* Compare ENTRY with DATA (both struct ttypes_filter) for a @TTypes
711    exception specification list we are thinking about adding.  */
712 /* ??? Currently we use the type lists in the order given.  Someone
713    should put these in some canonical order.  */
714
715 static int
716 ehspec_filter_eq (const void *pentry, const void *pdata)
717 {
718   const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
719   const struct ttypes_filter *data = (const struct ttypes_filter *) pdata;
720
721   return type_list_equal (entry->t, data->t);
722 }
723
724 /* Hash function for exception specification lists.  */
725
726 static hashval_t
727 ehspec_filter_hash (const void *pentry)
728 {
729   const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
730   hashval_t h = 0;
731   tree list;
732
733   for (list = entry->t; list ; list = TREE_CHAIN (list))
734     h = (h << 5) + (h >> 27) + TREE_HASH (TREE_VALUE (list));
735   return h;
736 }
737
738 /* Add TYPE (which may be NULL) to cfun->eh->ttype_data, using TYPES_HASH
739    to speed up the search.  Return the filter value to be used.  */
740
741 static int
742 add_ttypes_entry (htab_t ttypes_hash, tree type)
743 {
744   struct ttypes_filter **slot, *n;
745
746   slot = (struct ttypes_filter **)
747     htab_find_slot_with_hash (ttypes_hash, type, TREE_HASH (type), INSERT);
748
749   if ((n = *slot) == NULL)
750     {
751       /* Filter value is a 1 based table index.  */
752
753       n = XNEW (struct ttypes_filter);
754       n->t = type;
755       n->filter = VEC_length (tree, cfun->eh->ttype_data) + 1;
756       *slot = n;
757
758       VEC_safe_push (tree, gc, cfun->eh->ttype_data, type);
759     }
760
761   return n->filter;
762 }
763
764 /* Add LIST to cfun->eh->ehspec_data, using EHSPEC_HASH and TYPES_HASH
765    to speed up the search.  Return the filter value to be used.  */
766
767 static int
768 add_ehspec_entry (htab_t ehspec_hash, htab_t ttypes_hash, tree list)
769 {
770   struct ttypes_filter **slot, *n;
771   struct ttypes_filter dummy;
772
773   dummy.t = list;
774   slot = (struct ttypes_filter **)
775     htab_find_slot (ehspec_hash, &dummy, INSERT);
776
777   if ((n = *slot) == NULL)
778     {
779       int len;
780
781       if (targetm.arm_eabi_unwinder)
782         len = VEC_length (tree, cfun->eh->ehspec_data.arm_eabi);
783       else
784         len = VEC_length (uchar, cfun->eh->ehspec_data.other);
785
786       /* Filter value is a -1 based byte index into a uleb128 buffer.  */
787
788       n = XNEW (struct ttypes_filter);
789       n->t = list;
790       n->filter = -(len + 1);
791       *slot = n;
792
793       /* Generate a 0 terminated list of filter values.  */
794       for (; list ; list = TREE_CHAIN (list))
795         {
796           if (targetm.arm_eabi_unwinder)
797             VEC_safe_push (tree, gc, cfun->eh->ehspec_data.arm_eabi,
798                            TREE_VALUE (list));
799           else
800             {
801               /* Look up each type in the list and encode its filter
802                  value as a uleb128.  */
803               push_uleb128 (&cfun->eh->ehspec_data.other,
804                             add_ttypes_entry (ttypes_hash, TREE_VALUE (list)));
805             }
806         }
807       if (targetm.arm_eabi_unwinder)
808         VEC_safe_push (tree, gc, cfun->eh->ehspec_data.arm_eabi, NULL_TREE);
809       else
810         VEC_safe_push (uchar, gc, cfun->eh->ehspec_data.other, 0);
811     }
812
813   return n->filter;
814 }
815
816 /* Generate the action filter values to be used for CATCH and
817    ALLOWED_EXCEPTIONS regions.  When using dwarf2 exception regions,
818    we use lots of landing pads, and so every type or list can share
819    the same filter value, which saves table space.  */
820
821 void
822 assign_filter_values (void)
823 {
824   int i;
825   htab_t ttypes, ehspec;
826   eh_region r;
827   eh_catch c;
828
829   cfun->eh->ttype_data = VEC_alloc (tree, gc, 16);
830   if (targetm.arm_eabi_unwinder)
831     cfun->eh->ehspec_data.arm_eabi = VEC_alloc (tree, gc, 64);
832   else
833     cfun->eh->ehspec_data.other = VEC_alloc (uchar, gc, 64);
834
835   ttypes = htab_create (31, ttypes_filter_hash, ttypes_filter_eq, free);
836   ehspec = htab_create (31, ehspec_filter_hash, ehspec_filter_eq, free);
837
838   for (i = 1; VEC_iterate (eh_region, cfun->eh->region_array, i, r); ++i)
839     {
840       if (r == NULL)
841         continue;
842
843       switch (r->type)
844         {
845         case ERT_TRY:
846           for (c = r->u.eh_try.first_catch; c ; c = c->next_catch)
847             {
848               /* Whatever type_list is (NULL or true list), we build a list
849                  of filters for the region.  */
850               c->filter_list = NULL_TREE;
851
852               if (c->type_list != NULL)
853                 {
854                   /* Get a filter value for each of the types caught and store
855                      them in the region's dedicated list.  */
856                   tree tp_node = c->type_list;
857
858                   for ( ; tp_node; tp_node = TREE_CHAIN (tp_node))
859                     {
860                       int flt = add_ttypes_entry (ttypes, TREE_VALUE (tp_node));
861                       tree flt_node = build_int_cst (integer_type_node, flt);
862
863                       c->filter_list
864                         = tree_cons (NULL_TREE, flt_node, c->filter_list);
865                     }
866                 }
867               else
868                 {
869                   /* Get a filter value for the NULL list also since it
870                      will need an action record anyway.  */
871                   int flt = add_ttypes_entry (ttypes, NULL);
872                   tree flt_node = build_int_cst (integer_type_node, flt);
873
874                   c->filter_list
875                     = tree_cons (NULL_TREE, flt_node, NULL);
876                 }
877             }
878           break;
879
880         case ERT_ALLOWED_EXCEPTIONS:
881           r->u.allowed.filter
882             = add_ehspec_entry (ehspec, ttypes, r->u.allowed.type_list);
883           break;
884
885         default:
886           break;
887         }
888     }
889
890   htab_delete (ttypes);
891   htab_delete (ehspec);
892 }
893
894 /* Emit SEQ into basic block just before INSN (that is assumed to be
895    first instruction of some existing BB and return the newly
896    produced block.  */
897 static basic_block
898 emit_to_new_bb_before (rtx seq, rtx insn)
899 {
900   rtx last;
901   basic_block bb;
902   edge e;
903   edge_iterator ei;
904
905   /* If there happens to be a fallthru edge (possibly created by cleanup_cfg
906      call), we don't want it to go into newly created landing pad or other EH
907      construct.  */
908   for (ei = ei_start (BLOCK_FOR_INSN (insn)->preds); (e = ei_safe_edge (ei)); )
909     if (e->flags & EDGE_FALLTHRU)
910       force_nonfallthru (e);
911     else
912       ei_next (&ei);
913   last = emit_insn_before (seq, insn);
914   if (BARRIER_P (last))
915     last = PREV_INSN (last);
916   bb = create_basic_block (seq, last, BLOCK_FOR_INSN (insn)->prev_bb);
917   update_bb_for_insn (bb);
918   bb->flags |= BB_SUPERBLOCK;
919   return bb;
920 }
921 \f
922 /* Expand the extra code needed at landing pads for dwarf2 unwinding.  */
923
924 static void
925 dw2_build_landing_pads (void)
926 {
927   int i;
928   eh_landing_pad lp;
929
930   for (i = 1; VEC_iterate (eh_landing_pad, cfun->eh->lp_array, i, lp); ++i)
931     {
932       eh_region region;
933       basic_block bb;
934       rtx seq;
935       edge e;
936
937       if (lp == NULL || lp->post_landing_pad == NULL)
938         continue;
939
940       start_sequence ();
941
942       lp->landing_pad = gen_label_rtx ();
943       emit_label (lp->landing_pad);
944       LABEL_PRESERVE_P (lp->landing_pad) = 1;
945
946 #ifdef HAVE_exception_receiver
947       if (HAVE_exception_receiver)
948         emit_insn (gen_exception_receiver ());
949       else
950 #endif
951 #ifdef HAVE_nonlocal_goto_receiver
952         if (HAVE_nonlocal_goto_receiver)
953           emit_insn (gen_nonlocal_goto_receiver ());
954         else
955 #endif
956           { /* Nothing */ }
957
958       region = lp->region;
959       if (region->exc_ptr_reg)
960         emit_move_insn (region->exc_ptr_reg,
961                         gen_rtx_REG (ptr_mode, EH_RETURN_DATA_REGNO (0)));
962       if (region->filter_reg)
963         emit_move_insn (region->filter_reg,
964                         gen_rtx_REG (targetm.eh_return_filter_mode (),
965                                      EH_RETURN_DATA_REGNO (1)));
966
967       seq = get_insns ();
968       end_sequence ();
969
970       bb = emit_to_new_bb_before (seq, label_rtx (lp->post_landing_pad));
971       e = make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
972       e->count = bb->count;
973       e->probability = REG_BR_PROB_BASE;
974     }
975 }
976
977 \f
978 static VEC (int, heap) *sjlj_lp_call_site_index;
979
980 /* Process all active landing pads.  Assign each one a compact dispatch
981    index, and a call-site index.  */
982
983 static int
984 sjlj_assign_call_site_values (void)
985 {
986   htab_t ar_hash;
987   int i, disp_index;
988   eh_landing_pad lp;
989
990   crtl->eh.action_record_data = VEC_alloc (uchar, gc, 64);
991   ar_hash = htab_create (31, action_record_hash, action_record_eq, free);
992
993   disp_index = 0;
994   call_site_base = 1;
995   for (i = 1; VEC_iterate (eh_landing_pad, cfun->eh->lp_array, i, lp); ++i)
996     if (lp && lp->post_landing_pad)
997       {
998         int action, call_site;
999
1000         /* First: build the action table.  */
1001         action = collect_one_action_chain (ar_hash, lp->region);
1002
1003         /* Next: assign call-site values.  If dwarf2 terms, this would be
1004            the region number assigned by convert_to_eh_region_ranges, but
1005            handles no-action and must-not-throw differently.  */
1006         /* Map must-not-throw to otherwise unused call-site index 0.  */
1007         if (action == -2)
1008           call_site = 0;
1009         /* Map no-action to otherwise unused call-site index -1.  */
1010         else if (action == -1)
1011           call_site = -1;
1012         /* Otherwise, look it up in the table.  */
1013         else
1014           call_site = add_call_site (GEN_INT (disp_index), action, 0);
1015         VEC_replace (int, sjlj_lp_call_site_index, i, call_site);
1016
1017         disp_index++;
1018       }
1019
1020   htab_delete (ar_hash);
1021
1022   return disp_index;
1023 }
1024
1025 /* Emit code to record the current call-site index before every
1026    insn that can throw.  */
1027
1028 static void
1029 sjlj_mark_call_sites (void)
1030 {
1031   int last_call_site = -2;
1032   rtx insn, mem;
1033
1034   for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
1035     {
1036       eh_landing_pad lp;
1037       eh_region r;
1038       bool nothrow;
1039       int this_call_site;
1040       rtx before, p;
1041
1042       /* Reset value tracking at extended basic block boundaries.  */
1043       if (LABEL_P (insn))
1044         last_call_site = -2;
1045
1046       if (! INSN_P (insn))
1047         continue;
1048
1049       nothrow = get_eh_region_and_lp_from_rtx (insn, &r, &lp);
1050       if (nothrow)
1051         continue;
1052       if (lp)
1053         this_call_site = VEC_index (int, sjlj_lp_call_site_index, lp->index);
1054       else if (r == NULL)
1055         {
1056           /* Calls (and trapping insns) without notes are outside any
1057              exception handling region in this function.  Mark them as
1058              no action.  */
1059           this_call_site = -1;
1060         }
1061       else
1062         {
1063           gcc_assert (r->type == ERT_MUST_NOT_THROW);
1064           this_call_site = 0;
1065         }
1066
1067       if (this_call_site != -1)
1068         crtl->uses_eh_lsda = 1;
1069
1070       if (this_call_site == last_call_site)
1071         continue;
1072
1073       /* Don't separate a call from it's argument loads.  */
1074       before = insn;
1075       if (CALL_P (insn))
1076         before = find_first_parameter_load (insn, NULL_RTX);
1077
1078       start_sequence ();
1079       mem = adjust_address (crtl->eh.sjlj_fc, TYPE_MODE (integer_type_node),
1080                             sjlj_fc_call_site_ofs);
1081       emit_move_insn (mem, GEN_INT (this_call_site));
1082       p = get_insns ();
1083       end_sequence ();
1084
1085       emit_insn_before (p, before);
1086       last_call_site = this_call_site;
1087     }
1088 }
1089
1090 /* Construct the SjLj_Function_Context.  */
1091
1092 static void
1093 sjlj_emit_function_enter (rtx dispatch_label)
1094 {
1095   rtx fn_begin, fc, mem, seq;
1096   bool fn_begin_outside_block;
1097   rtx personality = get_personality_function (current_function_decl);
1098
1099   fc = crtl->eh.sjlj_fc;
1100
1101   start_sequence ();
1102
1103   /* We're storing this libcall's address into memory instead of
1104      calling it directly.  Thus, we must call assemble_external_libcall
1105      here, as we can not depend on emit_library_call to do it for us.  */
1106   assemble_external_libcall (personality);
1107   mem = adjust_address (fc, Pmode, sjlj_fc_personality_ofs);
1108   emit_move_insn (mem, personality);
1109
1110   mem = adjust_address (fc, Pmode, sjlj_fc_lsda_ofs);
1111   if (crtl->uses_eh_lsda)
1112     {
1113       char buf[20];
1114       rtx sym;
1115
1116       ASM_GENERATE_INTERNAL_LABEL (buf, "LLSDA", current_function_funcdef_no);
1117       sym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
1118       SYMBOL_REF_FLAGS (sym) = SYMBOL_FLAG_LOCAL;
1119       emit_move_insn (mem, sym);
1120     }
1121   else
1122     emit_move_insn (mem, const0_rtx);
1123
1124   if (dispatch_label)
1125     {
1126 #ifdef DONT_USE_BUILTIN_SETJMP
1127       rtx x, last;
1128       x = emit_library_call_value (setjmp_libfunc, NULL_RTX, LCT_RETURNS_TWICE,
1129                                    TYPE_MODE (integer_type_node), 1,
1130                                    plus_constant (XEXP (fc, 0),
1131                                                   sjlj_fc_jbuf_ofs), Pmode);
1132
1133       emit_cmp_and_jump_insns (x, const0_rtx, NE, 0,
1134                                TYPE_MODE (integer_type_node), 0,
1135                                dispatch_label);
1136       last = get_last_insn ();
1137       if (JUMP_P (last) && any_condjump_p (last))
1138         {
1139           gcc_assert (!find_reg_note (last, REG_BR_PROB, 0));
1140           add_reg_note (last, REG_BR_PROB, GEN_INT (REG_BR_PROB_BASE / 100));
1141         }
1142 #else
1143       expand_builtin_setjmp_setup (plus_constant (XEXP (fc, 0),
1144                                                   sjlj_fc_jbuf_ofs),
1145                                    dispatch_label);
1146 #endif
1147     }
1148
1149   emit_library_call (unwind_sjlj_register_libfunc, LCT_NORMAL, VOIDmode,
1150                      1, XEXP (fc, 0), Pmode);
1151
1152   seq = get_insns ();
1153   end_sequence ();
1154
1155   /* ??? Instead of doing this at the beginning of the function,
1156      do this in a block that is at loop level 0 and dominates all
1157      can_throw_internal instructions.  */
1158
1159   fn_begin_outside_block = true;
1160   for (fn_begin = get_insns (); ; fn_begin = NEXT_INSN (fn_begin))
1161     if (NOTE_P (fn_begin))
1162       {
1163         if (NOTE_KIND (fn_begin) == NOTE_INSN_FUNCTION_BEG)
1164           break;
1165         else if (NOTE_INSN_BASIC_BLOCK_P (fn_begin))
1166           fn_begin_outside_block = false;
1167       }
1168
1169   if (fn_begin_outside_block)
1170     insert_insn_on_edge (seq, single_succ_edge (ENTRY_BLOCK_PTR));
1171   else
1172     emit_insn_after (seq, fn_begin);
1173 }
1174
1175 /* Call back from expand_function_end to know where we should put
1176    the call to unwind_sjlj_unregister_libfunc if needed.  */
1177
1178 void
1179 sjlj_emit_function_exit_after (rtx after)
1180 {
1181   crtl->eh.sjlj_exit_after = after;
1182 }
1183
1184 static void
1185 sjlj_emit_function_exit (void)
1186 {
1187   rtx seq, insn;
1188
1189   start_sequence ();
1190
1191   emit_library_call (unwind_sjlj_unregister_libfunc, LCT_NORMAL, VOIDmode,
1192                      1, XEXP (crtl->eh.sjlj_fc, 0), Pmode);
1193
1194   seq = get_insns ();
1195   end_sequence ();
1196
1197   /* ??? Really this can be done in any block at loop level 0 that
1198      post-dominates all can_throw_internal instructions.  This is
1199      the last possible moment.  */
1200
1201   insn = crtl->eh.sjlj_exit_after;
1202   if (LABEL_P (insn))
1203     insn = NEXT_INSN (insn);
1204
1205   emit_insn_after (seq, insn);
1206 }
1207
1208 static void
1209 sjlj_emit_dispatch_table (rtx dispatch_label, int num_dispatch)
1210 {
1211   enum machine_mode unwind_word_mode = targetm.unwind_word_mode ();
1212   enum machine_mode filter_mode = targetm.eh_return_filter_mode ();
1213   eh_landing_pad lp;
1214   rtx mem, seq, fc, before, exc_ptr_reg, filter_reg;
1215   rtx first_reachable_label;
1216   basic_block bb;
1217   eh_region r;
1218   edge e;
1219   int i, disp_index;
1220   gimple switch_stmt;
1221
1222   fc = crtl->eh.sjlj_fc;
1223
1224   start_sequence ();
1225
1226   emit_label (dispatch_label);
1227
1228 #ifndef DONT_USE_BUILTIN_SETJMP
1229   expand_builtin_setjmp_receiver (dispatch_label);
1230
1231   /* The caller of expand_builtin_setjmp_receiver is responsible for
1232      making sure that the label doesn't vanish.  The only other caller
1233      is the expander for __builtin_setjmp_receiver, which places this
1234      label on the nonlocal_goto_label list.  Since we're modeling these
1235      CFG edges more exactly, we can use the forced_labels list instead.  */
1236   LABEL_PRESERVE_P (dispatch_label) = 1;
1237   forced_labels
1238     = gen_rtx_EXPR_LIST (VOIDmode, dispatch_label, forced_labels);
1239 #endif
1240
1241   /* Load up exc_ptr and filter values from the function context.  */
1242   mem = adjust_address (fc, unwind_word_mode, sjlj_fc_data_ofs);
1243   if (unwind_word_mode != ptr_mode)
1244     {
1245 #ifdef POINTERS_EXTEND_UNSIGNED
1246       mem = convert_memory_address (ptr_mode, mem);
1247 #else
1248       mem = convert_to_mode (ptr_mode, mem, 0);
1249 #endif
1250     }
1251   exc_ptr_reg = force_reg (ptr_mode, mem);
1252
1253   mem = adjust_address (fc, unwind_word_mode,
1254                         sjlj_fc_data_ofs + GET_MODE_SIZE (unwind_word_mode));
1255   if (unwind_word_mode != filter_mode)
1256     mem = convert_to_mode (filter_mode, mem, 0);
1257   filter_reg = force_reg (filter_mode, mem);
1258
1259   /* Jump to one of the directly reachable regions.  */
1260
1261   disp_index = 0;
1262   first_reachable_label = NULL;
1263
1264   /* If there's exactly one call site in the function, don't bother
1265      generating a switch statement.  */
1266   switch_stmt = NULL;
1267   if (num_dispatch > 1)
1268     {
1269       tree disp;
1270
1271       mem = adjust_address (fc, TYPE_MODE (integer_type_node),
1272                             sjlj_fc_call_site_ofs);
1273       disp = make_tree (integer_type_node, mem);
1274
1275       switch_stmt = gimple_build_switch_nlabels (num_dispatch, disp, NULL);
1276     }
1277
1278   for (i = 1; VEC_iterate (eh_landing_pad, cfun->eh->lp_array, i, lp); ++i)
1279     if (lp && lp->post_landing_pad)
1280       {
1281         rtx seq2, label;
1282
1283         start_sequence ();
1284
1285         lp->landing_pad = dispatch_label;
1286
1287         if (num_dispatch > 1)
1288           {
1289             tree t_label, case_elt, t;
1290
1291             t_label = create_artificial_label (UNKNOWN_LOCATION);
1292             t = build_int_cst (integer_type_node, disp_index);
1293             case_elt = build_case_label (t, NULL, t_label);
1294             gimple_switch_set_label (switch_stmt, disp_index, case_elt);
1295
1296             label = label_rtx (t_label);
1297           }
1298         else
1299           label = gen_label_rtx ();
1300
1301         if (disp_index == 0)
1302           first_reachable_label = label;
1303         emit_label (label);
1304
1305         r = lp->region;
1306         if (r->exc_ptr_reg)
1307           emit_move_insn (r->exc_ptr_reg, exc_ptr_reg);
1308         if (r->filter_reg)
1309           emit_move_insn (r->filter_reg, filter_reg);
1310
1311         seq2 = get_insns ();
1312         end_sequence ();
1313
1314         before = label_rtx (lp->post_landing_pad);
1315         bb = emit_to_new_bb_before (seq2, before);
1316         e = make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
1317         e->count = bb->count;
1318         e->probability = REG_BR_PROB_BASE;
1319
1320         disp_index++;
1321       }
1322   gcc_assert (disp_index == num_dispatch);
1323
1324   if (num_dispatch > 1)
1325     {
1326       expand_case (switch_stmt);
1327       expand_builtin_trap ();
1328     }
1329
1330   seq = get_insns ();
1331   end_sequence ();
1332
1333   bb = emit_to_new_bb_before (seq, first_reachable_label);
1334   if (num_dispatch == 1)
1335     {
1336       e = make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
1337       e->count = bb->count;
1338       e->probability = REG_BR_PROB_BASE;
1339     }
1340 }
1341
1342 static void
1343 sjlj_build_landing_pads (void)
1344 {
1345   int num_dispatch;
1346
1347   num_dispatch = VEC_length (eh_landing_pad, cfun->eh->lp_array);
1348   if (num_dispatch == 0)
1349     return;
1350   VEC_safe_grow (int, heap, sjlj_lp_call_site_index, num_dispatch);
1351
1352   num_dispatch = sjlj_assign_call_site_values ();
1353   if (num_dispatch > 0)
1354     {
1355       rtx dispatch_label = gen_label_rtx ();
1356       int align = STACK_SLOT_ALIGNMENT (sjlj_fc_type_node,
1357                                         TYPE_MODE (sjlj_fc_type_node),
1358                                         TYPE_ALIGN (sjlj_fc_type_node));
1359       crtl->eh.sjlj_fc
1360         = assign_stack_local (TYPE_MODE (sjlj_fc_type_node),
1361                               int_size_in_bytes (sjlj_fc_type_node),
1362                               align);
1363
1364       sjlj_mark_call_sites ();
1365       sjlj_emit_function_enter (dispatch_label);
1366       sjlj_emit_dispatch_table (dispatch_label, num_dispatch);
1367       sjlj_emit_function_exit ();
1368     }
1369
1370   /* If we do not have any landing pads, we may still need to register a
1371      personality routine and (empty) LSDA to handle must-not-throw regions.  */
1372   else if (function_needs_eh_personality (cfun) != eh_personality_none)
1373     {
1374       int align = STACK_SLOT_ALIGNMENT (sjlj_fc_type_node,
1375                                         TYPE_MODE (sjlj_fc_type_node),
1376                                         TYPE_ALIGN (sjlj_fc_type_node));
1377       crtl->eh.sjlj_fc
1378         = assign_stack_local (TYPE_MODE (sjlj_fc_type_node),
1379                               int_size_in_bytes (sjlj_fc_type_node),
1380                               align);
1381
1382       sjlj_mark_call_sites ();
1383       sjlj_emit_function_enter (NULL_RTX);
1384       sjlj_emit_function_exit ();
1385     }
1386
1387   VEC_free (int, heap, sjlj_lp_call_site_index);
1388 }
1389
1390 /* After initial rtl generation, call back to finish generating
1391    exception support code.  */
1392
1393 static void
1394 finish_eh_generation (void)
1395 {
1396   basic_block bb;
1397
1398   /* Construct the landing pads.  */
1399   if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ)
1400     sjlj_build_landing_pads ();
1401   else
1402     dw2_build_landing_pads ();
1403   break_superblocks ();
1404
1405   if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ
1406       /* Kludge for Alpha/Tru64 (see alpha_gp_save_rtx).  */
1407       || single_succ_edge (ENTRY_BLOCK_PTR)->insns.r)
1408     commit_edge_insertions ();
1409
1410   /* Redirect all EH edges from the post_landing_pad to the landing pad.  */
1411   FOR_EACH_BB (bb)
1412     {
1413       eh_landing_pad lp;
1414       edge_iterator ei;
1415       edge e;
1416
1417       lp = get_eh_landing_pad_from_rtx (BB_END (bb));
1418
1419       FOR_EACH_EDGE (e, ei, bb->succs)
1420         if (e->flags & EDGE_EH)
1421           break;
1422
1423       /* We should not have generated any new throwing insns during this
1424          pass, and we should not have lost any EH edges, so we only need
1425          to handle two cases here:
1426          (1) reachable handler and an existing edge to post-landing-pad,
1427          (2) no reachable handler and no edge.  */
1428       gcc_assert ((lp != NULL) == (e != NULL));
1429       if (lp != NULL)
1430         {
1431           gcc_assert (BB_HEAD (e->dest) == label_rtx (lp->post_landing_pad));
1432
1433           redirect_edge_succ (e, BLOCK_FOR_INSN (lp->landing_pad));
1434           e->flags |= (CALL_P (BB_END (bb))
1435                        ? EDGE_ABNORMAL | EDGE_ABNORMAL_CALL
1436                        : EDGE_ABNORMAL);
1437         }
1438     }
1439 }
1440
1441 static bool
1442 gate_handle_eh (void)
1443 {
1444   /* Nothing to do if no regions created.  */
1445   return cfun->eh->region_tree != NULL;
1446 }
1447
1448 /* Complete generation of exception handling code.  */
1449 static unsigned int
1450 rest_of_handle_eh (void)
1451 {
1452   finish_eh_generation ();
1453   cleanup_cfg (CLEANUP_NO_INSN_DEL);
1454   return 0;
1455 }
1456
1457 struct rtl_opt_pass pass_rtl_eh =
1458 {
1459  {
1460   RTL_PASS,
1461   "rtl_eh",                             /* name */
1462   gate_handle_eh,                       /* gate */
1463   rest_of_handle_eh,                    /* execute */
1464   NULL,                                 /* sub */
1465   NULL,                                 /* next */
1466   0,                                    /* static_pass_number */
1467   TV_JUMP,                              /* tv_id */
1468   0,                                    /* properties_required */
1469   0,                                    /* properties_provided */
1470   0,                                    /* properties_destroyed */
1471   0,                                    /* todo_flags_start */
1472   0                                     /* todo_flags_finish */
1473  }
1474 };
1475 \f
1476 /* This section handles removing dead code for flow.  */
1477
1478 void
1479 remove_eh_landing_pad (eh_landing_pad lp)
1480 {
1481   eh_landing_pad *pp;
1482
1483   for (pp = &lp->region->landing_pads; *pp != lp; pp = &(*pp)->next_lp)
1484     continue;
1485   *pp = lp->next_lp;
1486
1487   if (lp->post_landing_pad)
1488     EH_LANDING_PAD_NR (lp->post_landing_pad) = 0;
1489   VEC_replace (eh_landing_pad, cfun->eh->lp_array, lp->index, NULL);
1490 }
1491
1492 /* Splice REGION from the region tree.  */
1493
1494 void
1495 remove_eh_handler (eh_region region)
1496 {
1497   eh_region *pp, *pp_start, p, outer;
1498   eh_landing_pad lp;
1499
1500   for (lp = region->landing_pads; lp ; lp = lp->next_lp)
1501     {
1502       if (lp->post_landing_pad)
1503         EH_LANDING_PAD_NR (lp->post_landing_pad) = 0;
1504       VEC_replace (eh_landing_pad, cfun->eh->lp_array, lp->index, NULL);
1505     }
1506
1507   outer = region->outer;
1508   if (outer)
1509     pp_start = &outer->inner;
1510   else
1511     pp_start = &cfun->eh->region_tree;
1512   for (pp = pp_start, p = *pp; p != region; pp = &p->next_peer, p = *pp)
1513     continue;
1514   if (region->inner)
1515     {
1516       *pp = p = region->inner;
1517       do
1518         {
1519           p->outer = outer;
1520           pp = &p->next_peer;
1521           p = *pp;
1522         }
1523       while (p);
1524     }
1525   *pp = region->next_peer;
1526
1527   VEC_replace (eh_region, cfun->eh->region_array, region->index, NULL);
1528 }
1529
1530 /* Invokes CALLBACK for every exception handler landing pad label.
1531    Only used by reload hackery; should not be used by new code.  */
1532
1533 void
1534 for_each_eh_label (void (*callback) (rtx))
1535 {
1536   eh_landing_pad lp;
1537   int i;
1538
1539   for (i = 1; VEC_iterate (eh_landing_pad, cfun->eh->lp_array, i, lp); ++i)
1540     {
1541       if (lp)
1542         {
1543           rtx lab = lp->landing_pad;
1544           if (lab && LABEL_P (lab))
1545             (*callback) (lab);
1546         }
1547     }
1548 }
1549 \f
1550 /* Create the REG_EH_REGION note for INSN, given its ECF_FLAGS for a
1551    call insn.
1552
1553    At the gimple level, we use LP_NR
1554        > 0 : The statement transfers to landing pad LP_NR
1555        = 0 : The statement is outside any EH region
1556        < 0 : The statement is within MUST_NOT_THROW region -LP_NR.
1557
1558    At the rtl level, we use LP_NR
1559        > 0 : The insn transfers to landing pad LP_NR
1560        = 0 : The insn cannot throw
1561        < 0 : The insn is within MUST_NOT_THROW region -LP_NR
1562        = INT_MIN : The insn cannot throw or execute a nonlocal-goto.
1563        missing note: The insn is outside any EH region.
1564
1565   ??? This difference probably ought to be avoided.  We could stand
1566   to record nothrow for arbitrary gimple statements, and so avoid
1567   some moderately complex lookups in stmt_could_throw_p.  Perhaps
1568   NOTHROW should be mapped on both sides to INT_MIN.  Perhaps the
1569   no-nonlocal-goto property should be recorded elsewhere as a bit
1570   on the call_insn directly.  Perhaps we should make more use of
1571   attaching the trees to call_insns (reachable via symbol_ref in
1572   direct call cases) and just pull the data out of the trees.  */
1573
1574 void
1575 make_reg_eh_region_note (rtx insn, int ecf_flags, int lp_nr)
1576 {
1577   rtx value;
1578   if (ecf_flags & ECF_NOTHROW)
1579     value = const0_rtx;
1580   else if (lp_nr != 0)
1581     value = GEN_INT (lp_nr);
1582   else
1583     return;
1584   add_reg_note (insn, REG_EH_REGION, value);
1585 }
1586
1587 /* Create a REG_EH_REGION note for a CALL_INSN that cannot throw
1588    nor perform a non-local goto.  Replace the region note if it
1589    already exists.  */
1590
1591 void
1592 make_reg_eh_region_note_nothrow_nononlocal (rtx insn)
1593 {
1594   rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
1595   rtx intmin = GEN_INT (INT_MIN);
1596
1597   if (note != 0)
1598     XEXP (note, 0) = intmin;
1599   else
1600     add_reg_note (insn, REG_EH_REGION, intmin);
1601 }
1602
1603 /* Return true if INSN could throw, assuming no REG_EH_REGION note
1604    to the contrary.  */
1605
1606 bool
1607 insn_could_throw_p (const_rtx insn)
1608 {
1609   if (!flag_exceptions)
1610     return false;
1611   if (CALL_P (insn))
1612     return true;
1613   if (INSN_P (insn) && cfun->can_throw_non_call_exceptions)
1614     return may_trap_p (PATTERN (insn));
1615   return false;
1616 }
1617
1618 /* Copy an REG_EH_REGION note to each insn that might throw beginning
1619    at FIRST and ending at LAST.  NOTE_OR_INSN is either the source insn
1620    to look for a note, or the note itself.  */
1621
1622 void
1623 copy_reg_eh_region_note_forward (rtx note_or_insn, rtx first, rtx last)
1624 {
1625   rtx insn, note = note_or_insn;
1626
1627   if (INSN_P (note_or_insn))
1628     {
1629       note = find_reg_note (note_or_insn, REG_EH_REGION, NULL_RTX);
1630       if (note == NULL)
1631         return;
1632     }
1633   note = XEXP (note, 0);
1634
1635   for (insn = first; insn != last ; insn = NEXT_INSN (insn))
1636     if (!find_reg_note (insn, REG_EH_REGION, NULL_RTX)
1637         && insn_could_throw_p (insn))
1638       add_reg_note (insn, REG_EH_REGION, note);
1639 }
1640
1641 /* Likewise, but iterate backward.  */
1642
1643 void
1644 copy_reg_eh_region_note_backward (rtx note_or_insn, rtx last, rtx first)
1645 {
1646   rtx insn, note = note_or_insn;
1647
1648   if (INSN_P (note_or_insn))
1649     {
1650       note = find_reg_note (note_or_insn, REG_EH_REGION, NULL_RTX);
1651       if (note == NULL)
1652         return;
1653     }
1654   note = XEXP (note, 0);
1655
1656   for (insn = last; insn != first; insn = PREV_INSN (insn))
1657     if (insn_could_throw_p (insn))
1658       add_reg_note (insn, REG_EH_REGION, note);
1659 }
1660
1661
1662 /* Extract all EH information from INSN.  Return true if the insn
1663    was marked NOTHROW.  */
1664
1665 static bool
1666 get_eh_region_and_lp_from_rtx (const_rtx insn, eh_region *pr,
1667                                eh_landing_pad *plp)
1668 {
1669   eh_landing_pad lp = NULL;
1670   eh_region r = NULL;
1671   bool ret = false;
1672   rtx note;
1673   int lp_nr;
1674
1675   if (! INSN_P (insn))
1676     goto egress;
1677
1678   if (NONJUMP_INSN_P (insn)
1679       && GET_CODE (PATTERN (insn)) == SEQUENCE)
1680     insn = XVECEXP (PATTERN (insn), 0, 0);
1681
1682   note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
1683   if (!note)
1684     {
1685       ret = !insn_could_throw_p (insn);
1686       goto egress;
1687     }
1688
1689   lp_nr = INTVAL (XEXP (note, 0));
1690   if (lp_nr == 0 || lp_nr == INT_MIN)
1691     {
1692       ret = true;
1693       goto egress;
1694     }
1695
1696   if (lp_nr < 0)
1697     r = VEC_index (eh_region, cfun->eh->region_array, -lp_nr);
1698   else
1699     {
1700       lp = VEC_index (eh_landing_pad, cfun->eh->lp_array, lp_nr);
1701       r = lp->region;
1702     }
1703
1704  egress:
1705   *plp = lp;
1706   *pr = r;
1707   return ret;
1708 }
1709
1710 /* Return the landing pad to which INSN may go, or NULL if it does not
1711    have a reachable landing pad within this function.  */
1712
1713 eh_landing_pad
1714 get_eh_landing_pad_from_rtx (const_rtx insn)
1715 {
1716   eh_landing_pad lp;
1717   eh_region r;
1718
1719   get_eh_region_and_lp_from_rtx (insn, &r, &lp);
1720   return lp;
1721 }
1722
1723 /* Return the region to which INSN may go, or NULL if it does not
1724    have a reachable region within this function.  */
1725
1726 eh_region
1727 get_eh_region_from_rtx (const_rtx insn)
1728 {
1729   eh_landing_pad lp;
1730   eh_region r;
1731
1732   get_eh_region_and_lp_from_rtx (insn, &r, &lp);
1733   return r;
1734 }
1735
1736 /* Return true if INSN throws and is caught by something in this function.  */
1737
1738 bool
1739 can_throw_internal (const_rtx insn)
1740 {
1741   return get_eh_landing_pad_from_rtx (insn) != NULL;
1742 }
1743
1744 /* Return true if INSN throws and escapes from the current function.  */
1745
1746 bool
1747 can_throw_external (const_rtx insn)
1748 {
1749   eh_landing_pad lp;
1750   eh_region r;
1751   bool nothrow;
1752
1753   if (! INSN_P (insn))
1754     return false;
1755
1756   if (NONJUMP_INSN_P (insn)
1757       && GET_CODE (PATTERN (insn)) == SEQUENCE)
1758     {
1759       rtx seq = PATTERN (insn);
1760       int i, n = XVECLEN (seq, 0);
1761
1762       for (i = 0; i < n; i++)
1763         if (can_throw_external (XVECEXP (seq, 0, i)))
1764           return true;
1765
1766       return false;
1767     }
1768
1769   nothrow = get_eh_region_and_lp_from_rtx (insn, &r, &lp);
1770
1771   /* If we can't throw, we obviously can't throw external.  */
1772   if (nothrow)
1773     return false;
1774
1775   /* If we have an internal landing pad, then we're not external.  */
1776   if (lp != NULL)
1777     return false;
1778
1779   /* If we're not within an EH region, then we are external.  */
1780   if (r == NULL)
1781     return true;
1782
1783   /* The only thing that ought to be left is MUST_NOT_THROW regions,
1784      which don't always have landing pads.  */
1785   gcc_assert (r->type == ERT_MUST_NOT_THROW);
1786   return false;
1787 }
1788
1789 /* Return true if INSN cannot throw at all.  */
1790
1791 bool
1792 insn_nothrow_p (const_rtx insn)
1793 {
1794   eh_landing_pad lp;
1795   eh_region r;
1796
1797   if (! INSN_P (insn))
1798     return true;
1799
1800   if (NONJUMP_INSN_P (insn)
1801       && GET_CODE (PATTERN (insn)) == SEQUENCE)
1802     {
1803       rtx seq = PATTERN (insn);
1804       int i, n = XVECLEN (seq, 0);
1805
1806       for (i = 0; i < n; i++)
1807         if (!insn_nothrow_p (XVECEXP (seq, 0, i)))
1808           return false;
1809
1810       return true;
1811     }
1812
1813   return get_eh_region_and_lp_from_rtx (insn, &r, &lp);
1814 }
1815
1816 /* Return true if INSN can perform a non-local goto.  */
1817 /* ??? This test is here in this file because it (ab)uses REG_EH_REGION.  */
1818
1819 bool
1820 can_nonlocal_goto (const_rtx insn)
1821 {
1822   if (nonlocal_goto_handler_labels && CALL_P (insn))
1823     {
1824       rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
1825       if (!note || INTVAL (XEXP (note, 0)) != INT_MIN)
1826         return true;
1827     }
1828   return false;
1829 }
1830 \f
1831 /* Set TREE_NOTHROW and crtl->all_throwers_are_sibcalls.  */
1832
1833 static unsigned int
1834 set_nothrow_function_flags (void)
1835 {
1836   rtx insn;
1837
1838   crtl->nothrow = 1;
1839
1840   /* Assume crtl->all_throwers_are_sibcalls until we encounter
1841      something that can throw an exception.  We specifically exempt
1842      CALL_INSNs that are SIBLING_CALL_P, as these are really jumps,
1843      and can't throw.  Most CALL_INSNs are not SIBLING_CALL_P, so this
1844      is optimistic.  */
1845
1846   crtl->all_throwers_are_sibcalls = 1;
1847
1848   /* If we don't know that this implementation of the function will
1849      actually be used, then we must not set TREE_NOTHROW, since
1850      callers must not assume that this function does not throw.  */
1851   if (TREE_NOTHROW (current_function_decl))
1852     return 0;
1853
1854   if (! flag_exceptions)
1855     return 0;
1856
1857   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
1858     if (can_throw_external (insn))
1859       {
1860         crtl->nothrow = 0;
1861
1862         if (!CALL_P (insn) || !SIBLING_CALL_P (insn))
1863           {
1864             crtl->all_throwers_are_sibcalls = 0;
1865             return 0;
1866           }
1867       }
1868
1869   for (insn = crtl->epilogue_delay_list; insn;
1870        insn = XEXP (insn, 1))
1871     if (can_throw_external (insn))
1872       {
1873         crtl->nothrow = 0;
1874
1875         if (!CALL_P (insn) || !SIBLING_CALL_P (insn))
1876           {
1877             crtl->all_throwers_are_sibcalls = 0;
1878             return 0;
1879           }
1880       }
1881   if (crtl->nothrow
1882       && (cgraph_function_body_availability (cgraph_get_node
1883                                              (current_function_decl))
1884           >= AVAIL_AVAILABLE))
1885     {
1886       struct cgraph_node *node = cgraph_get_node (current_function_decl);
1887       struct cgraph_edge *e;
1888       for (e = node->callers; e; e = e->next_caller)
1889         e->can_throw_external = false;
1890       cgraph_set_nothrow_flag (node, true);
1891
1892       if (dump_file)
1893         fprintf (dump_file, "Marking function nothrow: %s\n\n",
1894                  current_function_name ());
1895     }
1896   return 0;
1897 }
1898
1899 struct rtl_opt_pass pass_set_nothrow_function_flags =
1900 {
1901  {
1902   RTL_PASS,
1903   "nothrow",                            /* name */
1904   NULL,                                 /* gate */
1905   set_nothrow_function_flags,           /* execute */
1906   NULL,                                 /* sub */
1907   NULL,                                 /* next */
1908   0,                                    /* static_pass_number */
1909   TV_NONE,                              /* tv_id */
1910   0,                                    /* properties_required */
1911   0,                                    /* properties_provided */
1912   0,                                    /* properties_destroyed */
1913   0,                                    /* todo_flags_start */
1914   0                                     /* todo_flags_finish */
1915  }
1916 };
1917
1918 \f
1919 /* Various hooks for unwind library.  */
1920
1921 /* Expand the EH support builtin functions:
1922    __builtin_eh_pointer and __builtin_eh_filter.  */
1923
1924 static eh_region
1925 expand_builtin_eh_common (tree region_nr_t)
1926 {
1927   HOST_WIDE_INT region_nr;
1928   eh_region region;
1929
1930   gcc_assert (host_integerp (region_nr_t, 0));
1931   region_nr = tree_low_cst (region_nr_t, 0);
1932
1933   region = VEC_index (eh_region, cfun->eh->region_array, region_nr);
1934
1935   /* ??? We shouldn't have been able to delete a eh region without
1936      deleting all the code that depended on it.  */
1937   gcc_assert (region != NULL);
1938
1939   return region;
1940 }
1941
1942 /* Expand to the exc_ptr value from the given eh region.  */
1943
1944 rtx
1945 expand_builtin_eh_pointer (tree exp)
1946 {
1947   eh_region region
1948     = expand_builtin_eh_common (CALL_EXPR_ARG (exp, 0));
1949   if (region->exc_ptr_reg == NULL)
1950     region->exc_ptr_reg = gen_reg_rtx (ptr_mode);
1951   return region->exc_ptr_reg;
1952 }
1953
1954 /* Expand to the filter value from the given eh region.  */
1955
1956 rtx
1957 expand_builtin_eh_filter (tree exp)
1958 {
1959   eh_region region
1960     = expand_builtin_eh_common (CALL_EXPR_ARG (exp, 0));
1961   if (region->filter_reg == NULL)
1962     region->filter_reg = gen_reg_rtx (targetm.eh_return_filter_mode ());
1963   return region->filter_reg;
1964 }
1965
1966 /* Copy the exc_ptr and filter values from one landing pad's registers
1967    to another.  This is used to inline the resx statement.  */
1968
1969 rtx
1970 expand_builtin_eh_copy_values (tree exp)
1971 {
1972   eh_region dst
1973     = expand_builtin_eh_common (CALL_EXPR_ARG (exp, 0));
1974   eh_region src
1975     = expand_builtin_eh_common (CALL_EXPR_ARG (exp, 1));
1976   enum machine_mode fmode = targetm.eh_return_filter_mode ();
1977
1978   if (dst->exc_ptr_reg == NULL)
1979     dst->exc_ptr_reg = gen_reg_rtx (ptr_mode);
1980   if (src->exc_ptr_reg == NULL)
1981     src->exc_ptr_reg = gen_reg_rtx (ptr_mode);
1982
1983   if (dst->filter_reg == NULL)
1984     dst->filter_reg = gen_reg_rtx (fmode);
1985   if (src->filter_reg == NULL)
1986     src->filter_reg = gen_reg_rtx (fmode);
1987
1988   emit_move_insn (dst->exc_ptr_reg, src->exc_ptr_reg);
1989   emit_move_insn (dst->filter_reg, src->filter_reg);
1990
1991   return const0_rtx;
1992 }
1993
1994 /* Do any necessary initialization to access arbitrary stack frames.
1995    On the SPARC, this means flushing the register windows.  */
1996
1997 void
1998 expand_builtin_unwind_init (void)
1999 {
2000   /* Set this so all the registers get saved in our frame; we need to be
2001      able to copy the saved values for any registers from frames we unwind.  */
2002   crtl->saves_all_registers = 1;
2003
2004 #ifdef SETUP_FRAME_ADDRESSES
2005   SETUP_FRAME_ADDRESSES ();
2006 #endif
2007 }
2008
2009 /* Map a non-negative number to an eh return data register number; expands
2010    to -1 if no return data register is associated with the input number.
2011    At least the inputs 0 and 1 must be mapped; the target may provide more.  */
2012
2013 rtx
2014 expand_builtin_eh_return_data_regno (tree exp)
2015 {
2016   tree which = CALL_EXPR_ARG (exp, 0);
2017   unsigned HOST_WIDE_INT iwhich;
2018
2019   if (TREE_CODE (which) != INTEGER_CST)
2020     {
2021       error ("argument of %<__builtin_eh_return_regno%> must be constant");
2022       return constm1_rtx;
2023     }
2024
2025   iwhich = tree_low_cst (which, 1);
2026   iwhich = EH_RETURN_DATA_REGNO (iwhich);
2027   if (iwhich == INVALID_REGNUM)
2028     return constm1_rtx;
2029
2030 #ifdef DWARF_FRAME_REGNUM
2031   iwhich = DWARF_FRAME_REGNUM (iwhich);
2032 #else
2033   iwhich = DBX_REGISTER_NUMBER (iwhich);
2034 #endif
2035
2036   return GEN_INT (iwhich);
2037 }
2038
2039 /* Given a value extracted from the return address register or stack slot,
2040    return the actual address encoded in that value.  */
2041
2042 rtx
2043 expand_builtin_extract_return_addr (tree addr_tree)
2044 {
2045   rtx addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
2046
2047   if (GET_MODE (addr) != Pmode
2048       && GET_MODE (addr) != VOIDmode)
2049     {
2050 #ifdef POINTERS_EXTEND_UNSIGNED
2051       addr = convert_memory_address (Pmode, addr);
2052 #else
2053       addr = convert_to_mode (Pmode, addr, 0);
2054 #endif
2055     }
2056
2057   /* First mask out any unwanted bits.  */
2058 #ifdef MASK_RETURN_ADDR
2059   expand_and (Pmode, addr, MASK_RETURN_ADDR, addr);
2060 #endif
2061
2062   /* Then adjust to find the real return address.  */
2063 #if defined (RETURN_ADDR_OFFSET)
2064   addr = plus_constant (addr, RETURN_ADDR_OFFSET);
2065 #endif
2066
2067   return addr;
2068 }
2069
2070 /* Given an actual address in addr_tree, do any necessary encoding
2071    and return the value to be stored in the return address register or
2072    stack slot so the epilogue will return to that address.  */
2073
2074 rtx
2075 expand_builtin_frob_return_addr (tree addr_tree)
2076 {
2077   rtx addr = expand_expr (addr_tree, NULL_RTX, ptr_mode, EXPAND_NORMAL);
2078
2079   addr = convert_memory_address (Pmode, addr);
2080
2081 #ifdef RETURN_ADDR_OFFSET
2082   addr = force_reg (Pmode, addr);
2083   addr = plus_constant (addr, -RETURN_ADDR_OFFSET);
2084 #endif
2085
2086   return addr;
2087 }
2088
2089 /* Set up the epilogue with the magic bits we'll need to return to the
2090    exception handler.  */
2091
2092 void
2093 expand_builtin_eh_return (tree stackadj_tree ATTRIBUTE_UNUSED,
2094                           tree handler_tree)
2095 {
2096   rtx tmp;
2097
2098 #ifdef EH_RETURN_STACKADJ_RTX
2099   tmp = expand_expr (stackadj_tree, crtl->eh.ehr_stackadj,
2100                      VOIDmode, EXPAND_NORMAL);
2101   tmp = convert_memory_address (Pmode, tmp);
2102   if (!crtl->eh.ehr_stackadj)
2103     crtl->eh.ehr_stackadj = copy_to_reg (tmp);
2104   else if (tmp != crtl->eh.ehr_stackadj)
2105     emit_move_insn (crtl->eh.ehr_stackadj, tmp);
2106 #endif
2107
2108   tmp = expand_expr (handler_tree, crtl->eh.ehr_handler,
2109                      VOIDmode, EXPAND_NORMAL);
2110   tmp = convert_memory_address (Pmode, tmp);
2111   if (!crtl->eh.ehr_handler)
2112     crtl->eh.ehr_handler = copy_to_reg (tmp);
2113   else if (tmp != crtl->eh.ehr_handler)
2114     emit_move_insn (crtl->eh.ehr_handler, tmp);
2115
2116   if (!crtl->eh.ehr_label)
2117     crtl->eh.ehr_label = gen_label_rtx ();
2118   emit_jump (crtl->eh.ehr_label);
2119 }
2120
2121 /* Expand __builtin_eh_return.  This exit path from the function loads up
2122    the eh return data registers, adjusts the stack, and branches to a
2123    given PC other than the normal return address.  */
2124
2125 void
2126 expand_eh_return (void)
2127 {
2128   rtx around_label;
2129
2130   if (! crtl->eh.ehr_label)
2131     return;
2132
2133   crtl->calls_eh_return = 1;
2134
2135 #ifdef EH_RETURN_STACKADJ_RTX
2136   emit_move_insn (EH_RETURN_STACKADJ_RTX, const0_rtx);
2137 #endif
2138
2139   around_label = gen_label_rtx ();
2140   emit_jump (around_label);
2141
2142   emit_label (crtl->eh.ehr_label);
2143   clobber_return_register ();
2144
2145 #ifdef EH_RETURN_STACKADJ_RTX
2146   emit_move_insn (EH_RETURN_STACKADJ_RTX, crtl->eh.ehr_stackadj);
2147 #endif
2148
2149 #ifdef HAVE_eh_return
2150   if (HAVE_eh_return)
2151     emit_insn (gen_eh_return (crtl->eh.ehr_handler));
2152   else
2153 #endif
2154     {
2155 #ifdef EH_RETURN_HANDLER_RTX
2156       emit_move_insn (EH_RETURN_HANDLER_RTX, crtl->eh.ehr_handler);
2157 #else
2158       error ("__builtin_eh_return not supported on this target");
2159 #endif
2160     }
2161
2162   emit_label (around_label);
2163 }
2164
2165 /* Convert a ptr_mode address ADDR_TREE to a Pmode address controlled by
2166    POINTERS_EXTEND_UNSIGNED and return it.  */
2167
2168 rtx
2169 expand_builtin_extend_pointer (tree addr_tree)
2170 {
2171   rtx addr = expand_expr (addr_tree, NULL_RTX, ptr_mode, EXPAND_NORMAL);
2172   int extend;
2173
2174 #ifdef POINTERS_EXTEND_UNSIGNED
2175   extend = POINTERS_EXTEND_UNSIGNED;
2176 #else
2177   /* The previous EH code did an unsigned extend by default, so we do this also
2178      for consistency.  */
2179   extend = 1;
2180 #endif
2181
2182   return convert_modes (targetm.unwind_word_mode (), ptr_mode, addr, extend);
2183 }
2184 \f
2185 /* In the following functions, we represent entries in the action table
2186    as 1-based indices.  Special cases are:
2187
2188          0:     null action record, non-null landing pad; implies cleanups
2189         -1:     null action record, null landing pad; implies no action
2190         -2:     no call-site entry; implies must_not_throw
2191         -3:     we have yet to process outer regions
2192
2193    Further, no special cases apply to the "next" field of the record.
2194    For next, 0 means end of list.  */
2195
2196 struct action_record
2197 {
2198   int offset;
2199   int filter;
2200   int next;
2201 };
2202
2203 static int
2204 action_record_eq (const void *pentry, const void *pdata)
2205 {
2206   const struct action_record *entry = (const struct action_record *) pentry;
2207   const struct action_record *data = (const struct action_record *) pdata;
2208   return entry->filter == data->filter && entry->next == data->next;
2209 }
2210
2211 static hashval_t
2212 action_record_hash (const void *pentry)
2213 {
2214   const struct action_record *entry = (const struct action_record *) pentry;
2215   return entry->next * 1009 + entry->filter;
2216 }
2217
2218 static int
2219 add_action_record (htab_t ar_hash, int filter, int next)
2220 {
2221   struct action_record **slot, *new_ar, tmp;
2222
2223   tmp.filter = filter;
2224   tmp.next = next;
2225   slot = (struct action_record **) htab_find_slot (ar_hash, &tmp, INSERT);
2226
2227   if ((new_ar = *slot) == NULL)
2228     {
2229       new_ar = XNEW (struct action_record);
2230       new_ar->offset = VEC_length (uchar, crtl->eh.action_record_data) + 1;
2231       new_ar->filter = filter;
2232       new_ar->next = next;
2233       *slot = new_ar;
2234
2235       /* The filter value goes in untouched.  The link to the next
2236          record is a "self-relative" byte offset, or zero to indicate
2237          that there is no next record.  So convert the absolute 1 based
2238          indices we've been carrying around into a displacement.  */
2239
2240       push_sleb128 (&crtl->eh.action_record_data, filter);
2241       if (next)
2242         next -= VEC_length (uchar, crtl->eh.action_record_data) + 1;
2243       push_sleb128 (&crtl->eh.action_record_data, next);
2244     }
2245
2246   return new_ar->offset;
2247 }
2248
2249 static int
2250 collect_one_action_chain (htab_t ar_hash, eh_region region)
2251 {
2252   int next;
2253
2254   /* If we've reached the top of the region chain, then we have
2255      no actions, and require no landing pad.  */
2256   if (region == NULL)
2257     return -1;
2258
2259   switch (region->type)
2260     {
2261     case ERT_CLEANUP:
2262       {
2263         eh_region r;
2264         /* A cleanup adds a zero filter to the beginning of the chain, but
2265            there are special cases to look out for.  If there are *only*
2266            cleanups along a path, then it compresses to a zero action.
2267            Further, if there are multiple cleanups along a path, we only
2268            need to represent one of them, as that is enough to trigger
2269            entry to the landing pad at runtime.  */
2270         next = collect_one_action_chain (ar_hash, region->outer);
2271         if (next <= 0)
2272           return 0;
2273         for (r = region->outer; r ; r = r->outer)
2274           if (r->type == ERT_CLEANUP)
2275             return next;
2276         return add_action_record (ar_hash, 0, next);
2277       }
2278
2279     case ERT_TRY:
2280       {
2281         eh_catch c;
2282
2283         /* Process the associated catch regions in reverse order.
2284            If there's a catch-all handler, then we don't need to
2285            search outer regions.  Use a magic -3 value to record
2286            that we haven't done the outer search.  */
2287         next = -3;
2288         for (c = region->u.eh_try.last_catch; c ; c = c->prev_catch)
2289           {
2290             if (c->type_list == NULL)
2291               {
2292                 /* Retrieve the filter from the head of the filter list
2293                    where we have stored it (see assign_filter_values).  */
2294                 int filter = TREE_INT_CST_LOW (TREE_VALUE (c->filter_list));
2295                 next = add_action_record (ar_hash, filter, 0);
2296               }
2297             else
2298               {
2299                 /* Once the outer search is done, trigger an action record for
2300                    each filter we have.  */
2301                 tree flt_node;
2302
2303                 if (next == -3)
2304                   {
2305                     next = collect_one_action_chain (ar_hash, region->outer);
2306
2307                     /* If there is no next action, terminate the chain.  */
2308                     if (next == -1)
2309                       next = 0;
2310                     /* If all outer actions are cleanups or must_not_throw,
2311                        we'll have no action record for it, since we had wanted
2312                        to encode these states in the call-site record directly.
2313                        Add a cleanup action to the chain to catch these.  */
2314                     else if (next <= 0)
2315                       next = add_action_record (ar_hash, 0, 0);
2316                   }
2317
2318                 flt_node = c->filter_list;
2319                 for (; flt_node; flt_node = TREE_CHAIN (flt_node))
2320                   {
2321                     int filter = TREE_INT_CST_LOW (TREE_VALUE (flt_node));
2322                     next = add_action_record (ar_hash, filter, next);
2323                   }
2324               }
2325           }
2326         return next;
2327       }
2328
2329     case ERT_ALLOWED_EXCEPTIONS:
2330       /* An exception specification adds its filter to the
2331          beginning of the chain.  */
2332       next = collect_one_action_chain (ar_hash, region->outer);
2333
2334       /* If there is no next action, terminate the chain.  */
2335       if (next == -1)
2336         next = 0;
2337       /* If all outer actions are cleanups or must_not_throw,
2338          we'll have no action record for it, since we had wanted
2339          to encode these states in the call-site record directly.
2340          Add a cleanup action to the chain to catch these.  */
2341       else if (next <= 0)
2342         next = add_action_record (ar_hash, 0, 0);
2343
2344       return add_action_record (ar_hash, region->u.allowed.filter, next);
2345
2346     case ERT_MUST_NOT_THROW:
2347       /* A must-not-throw region with no inner handlers or cleanups
2348          requires no call-site entry.  Note that this differs from
2349          the no handler or cleanup case in that we do require an lsda
2350          to be generated.  Return a magic -2 value to record this.  */
2351       return -2;
2352     }
2353
2354   gcc_unreachable ();
2355 }
2356
2357 static int
2358 add_call_site (rtx landing_pad, int action, int section)
2359 {
2360   call_site_record record;
2361
2362   record = ggc_alloc_call_site_record_d ();
2363   record->landing_pad = landing_pad;
2364   record->action = action;
2365
2366   VEC_safe_push (call_site_record, gc,
2367                  crtl->eh.call_site_record[section], record);
2368
2369   return call_site_base + VEC_length (call_site_record,
2370                                       crtl->eh.call_site_record[section]) - 1;
2371 }
2372
2373 /* Turn REG_EH_REGION notes back into NOTE_INSN_EH_REGION notes.
2374    The new note numbers will not refer to region numbers, but
2375    instead to call site entries.  */
2376
2377 static unsigned int
2378 convert_to_eh_region_ranges (void)
2379 {
2380   rtx insn, iter, note;
2381   htab_t ar_hash;
2382   int last_action = -3;
2383   rtx last_action_insn = NULL_RTX;
2384   rtx last_landing_pad = NULL_RTX;
2385   rtx first_no_action_insn = NULL_RTX;
2386   int call_site = 0;
2387   int cur_sec = 0;
2388   rtx section_switch_note = NULL_RTX;
2389   rtx first_no_action_insn_before_switch = NULL_RTX;
2390   rtx last_no_action_insn_before_switch = NULL_RTX;
2391   rtx *pad_map = NULL;
2392   sbitmap pad_loc = NULL;
2393   int min_labelno = 0, max_labelno = 0;
2394   int saved_call_site_base = call_site_base;
2395
2396   crtl->eh.action_record_data = VEC_alloc (uchar, gc, 64);
2397
2398   ar_hash = htab_create (31, action_record_hash, action_record_eq, free);
2399
2400   for (iter = get_insns (); iter ; iter = NEXT_INSN (iter))
2401     if (INSN_P (iter))
2402       {
2403         eh_landing_pad lp;
2404         eh_region region;
2405         bool nothrow;
2406         int this_action;
2407         rtx this_landing_pad;
2408
2409         insn = iter;
2410         if (NONJUMP_INSN_P (insn)
2411             && GET_CODE (PATTERN (insn)) == SEQUENCE)
2412           insn = XVECEXP (PATTERN (insn), 0, 0);
2413
2414         nothrow = get_eh_region_and_lp_from_rtx (insn, &region, &lp);
2415         if (nothrow)
2416           continue;
2417         if (region)
2418           this_action = collect_one_action_chain (ar_hash, region);
2419         else
2420           this_action = -1;
2421
2422         /* Existence of catch handlers, or must-not-throw regions
2423            implies that an lsda is needed (even if empty).  */
2424         if (this_action != -1)
2425           crtl->uses_eh_lsda = 1;
2426
2427         /* Delay creation of region notes for no-action regions
2428            until we're sure that an lsda will be required.  */
2429         else if (last_action == -3)
2430           {
2431             first_no_action_insn = iter;
2432             last_action = -1;
2433           }
2434
2435         if (this_action >= 0)
2436           this_landing_pad = lp->landing_pad;
2437         else
2438           this_landing_pad = NULL_RTX;
2439
2440         /* Differing actions or landing pads implies a change in call-site
2441            info, which implies some EH_REGION note should be emitted.  */
2442         if (last_action != this_action
2443             || last_landing_pad != this_landing_pad)
2444           {
2445             /* If there is a queued no-action region in the other section
2446                with hot/cold partitioning, emit it now.  */
2447             if (first_no_action_insn_before_switch)
2448               {
2449                 gcc_assert (this_action != -1
2450                             && last_action == (first_no_action_insn
2451                                                ? -1 : -3));
2452                 call_site = add_call_site (NULL_RTX, 0, 0);
2453                 note = emit_note_before (NOTE_INSN_EH_REGION_BEG,
2454                                          first_no_action_insn_before_switch);
2455                 NOTE_EH_HANDLER (note) = call_site;
2456                 note = emit_note_after (NOTE_INSN_EH_REGION_END,
2457                                         last_no_action_insn_before_switch);
2458                 NOTE_EH_HANDLER (note) = call_site;
2459                 gcc_assert (last_action != -3
2460                             || (last_action_insn
2461                                 == last_no_action_insn_before_switch));
2462                 first_no_action_insn_before_switch = NULL_RTX;
2463                 last_no_action_insn_before_switch = NULL_RTX;
2464                 call_site_base++;
2465               }
2466             /* If we'd not seen a previous action (-3) or the previous
2467                action was must-not-throw (-2), then we do not need an
2468                end note.  */
2469             if (last_action >= -1)
2470               {
2471                 /* If we delayed the creation of the begin, do it now.  */
2472                 if (first_no_action_insn)
2473                   {
2474                     call_site = add_call_site (NULL_RTX, 0, cur_sec);
2475                     note = emit_note_before (NOTE_INSN_EH_REGION_BEG,
2476                                              first_no_action_insn);
2477                     NOTE_EH_HANDLER (note) = call_site;
2478                     first_no_action_insn = NULL_RTX;
2479                   }
2480
2481                 note = emit_note_after (NOTE_INSN_EH_REGION_END,
2482                                         last_action_insn);
2483                 NOTE_EH_HANDLER (note) = call_site;
2484               }
2485
2486             /* If the new action is must-not-throw, then no region notes
2487                are created.  */
2488             if (this_action >= -1)
2489               {
2490                 call_site = add_call_site (this_landing_pad,
2491                                            this_action < 0 ? 0 : this_action,
2492                                            cur_sec);
2493                 note = emit_note_before (NOTE_INSN_EH_REGION_BEG, iter);
2494                 NOTE_EH_HANDLER (note) = call_site;
2495               }
2496
2497             last_action = this_action;
2498             last_landing_pad = this_landing_pad;
2499           }
2500         last_action_insn = iter;
2501       }
2502     else if (NOTE_P (iter)
2503              && NOTE_KIND (iter) == NOTE_INSN_SWITCH_TEXT_SECTIONS)
2504       {
2505         gcc_assert (section_switch_note == NULL_RTX);
2506         gcc_assert (flag_reorder_blocks_and_partition);
2507         section_switch_note = iter;
2508         if (first_no_action_insn)
2509           {
2510             first_no_action_insn_before_switch = first_no_action_insn;
2511             last_no_action_insn_before_switch = last_action_insn;
2512             first_no_action_insn = NULL_RTX;
2513             gcc_assert (last_action == -1);
2514             last_action = -3;
2515           }
2516         /* Force closing of current EH region before section switch and
2517            opening a new one afterwards.  */
2518         else if (last_action != -3)
2519           last_landing_pad = pc_rtx;
2520         call_site_base += VEC_length (call_site_record,
2521                                       crtl->eh.call_site_record[cur_sec]);
2522         cur_sec++;
2523         gcc_assert (crtl->eh.call_site_record[cur_sec] == NULL);
2524         crtl->eh.call_site_record[cur_sec]
2525           = VEC_alloc (call_site_record, gc, 10);
2526         max_labelno = max_label_num ();
2527         min_labelno = get_first_label_num ();
2528         pad_map = XCNEWVEC (rtx, max_labelno - min_labelno + 1);
2529         pad_loc = sbitmap_alloc (max_labelno - min_labelno + 1);
2530       }
2531     else if (LABEL_P (iter) && pad_map)
2532       SET_BIT (pad_loc, CODE_LABEL_NUMBER (iter) - min_labelno);
2533
2534   if (last_action >= -1 && ! first_no_action_insn)
2535     {
2536       note = emit_note_after (NOTE_INSN_EH_REGION_END, last_action_insn);
2537       NOTE_EH_HANDLER (note) = call_site;
2538     }
2539
2540   call_site_base = saved_call_site_base;
2541
2542   if (pad_map)
2543     {
2544       /* When doing hot/cold partitioning, ensure landing pads are
2545          always in the same section as the EH region, .gcc_except_table
2546          can't express it otherwise.  */
2547       for (cur_sec = 0; cur_sec < 2; cur_sec++)
2548         {
2549           int i, idx;
2550           int n = VEC_length (call_site_record,
2551                               crtl->eh.call_site_record[cur_sec]);
2552           basic_block prev_bb = NULL, padbb;
2553
2554           for (i = 0; i < n; ++i)
2555             {
2556               struct call_site_record_d *cs =
2557                 VEC_index (call_site_record,
2558                            crtl->eh.call_site_record[cur_sec], i);
2559               rtx jump, note;
2560
2561               if (cs->landing_pad == NULL_RTX)
2562                 continue;
2563               idx = CODE_LABEL_NUMBER (cs->landing_pad) - min_labelno;
2564               /* If the landing pad is in the correct section, nothing
2565                  is needed.  */
2566               if (TEST_BIT (pad_loc, idx) ^ (cur_sec == 0))
2567                 continue;
2568               /* Otherwise, if we haven't seen this pad yet, we need to
2569                  add a new label and jump to the correct section.  */
2570               if (pad_map[idx] == NULL_RTX)
2571                 {
2572                   pad_map[idx] = gen_label_rtx ();
2573                   if (prev_bb == NULL)
2574                     for (iter = section_switch_note;
2575                          iter; iter = PREV_INSN (iter))
2576                       if (NOTE_INSN_BASIC_BLOCK_P (iter))
2577                         {
2578                           prev_bb = NOTE_BASIC_BLOCK (iter);
2579                           break;
2580                         }
2581                   if (cur_sec == 0)
2582                     {
2583                       note = emit_label_before (pad_map[idx],
2584                                                 section_switch_note);
2585                       jump = emit_jump_insn_before (gen_jump (cs->landing_pad),
2586                                                     section_switch_note);
2587                     }
2588                   else
2589                     {
2590                       jump = emit_jump_insn_after (gen_jump (cs->landing_pad),
2591                                                    section_switch_note);
2592                       note = emit_label_after (pad_map[idx],
2593                                                section_switch_note);
2594                     }
2595                   JUMP_LABEL (jump) = cs->landing_pad;
2596                   add_reg_note (jump, REG_CROSSING_JUMP, NULL_RTX);
2597                   iter = NEXT_INSN (cs->landing_pad);
2598                   if (iter && NOTE_INSN_BASIC_BLOCK_P (iter))
2599                     padbb = NOTE_BASIC_BLOCK (iter);
2600                   else
2601                     padbb = NULL;
2602                   if (padbb && prev_bb
2603                       && BB_PARTITION (padbb) != BB_UNPARTITIONED)
2604                     {
2605                       basic_block bb;
2606                       int part
2607                         = BB_PARTITION (padbb) == BB_COLD_PARTITION
2608                           ? BB_HOT_PARTITION : BB_COLD_PARTITION;
2609                       edge_iterator ei;
2610                       edge e;
2611
2612                       bb = create_basic_block (note, jump, prev_bb);
2613                       make_single_succ_edge (bb, padbb, EDGE_CROSSING);
2614                       BB_SET_PARTITION (bb, part);
2615                       for (ei = ei_start (padbb->preds);
2616                            (e = ei_safe_edge (ei)); )
2617                         {
2618                           if ((e->flags & (EDGE_EH|EDGE_CROSSING))
2619                               == (EDGE_EH|EDGE_CROSSING))
2620                             {
2621                               redirect_edge_succ (e, bb);
2622                               e->flags &= ~EDGE_CROSSING;
2623                             }
2624                           else
2625                             ei_next (&ei);
2626                         }
2627                       if (cur_sec == 0)
2628                         prev_bb = bb;
2629                     }
2630                 }
2631               cs->landing_pad = pad_map[idx];
2632             }
2633         }
2634
2635       sbitmap_free (pad_loc);
2636       XDELETEVEC (pad_map);
2637     }
2638
2639   htab_delete (ar_hash);
2640   return 0;
2641 }
2642
2643 static bool
2644 gate_convert_to_eh_region_ranges (void)
2645 {
2646   /* Nothing to do for SJLJ exceptions or if no regions created.  */
2647   if (cfun->eh->region_tree == NULL)
2648     return false;
2649   if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ)
2650     return false;
2651   return true;
2652 }
2653
2654 struct rtl_opt_pass pass_convert_to_eh_region_ranges =
2655 {
2656  {
2657   RTL_PASS,
2658   "eh_ranges",                          /* name */
2659   gate_convert_to_eh_region_ranges,     /* gate */
2660   convert_to_eh_region_ranges,          /* execute */
2661   NULL,                                 /* sub */
2662   NULL,                                 /* next */
2663   0,                                    /* static_pass_number */
2664   TV_NONE,                              /* tv_id */
2665   0,                                    /* properties_required */
2666   0,                                    /* properties_provided */
2667   0,                                    /* properties_destroyed */
2668   0,                                    /* todo_flags_start */
2669   0                                     /* todo_flags_finish */
2670  }
2671 };
2672 \f
2673 static void
2674 push_uleb128 (VEC (uchar, gc) **data_area, unsigned int value)
2675 {
2676   do
2677     {
2678       unsigned char byte = value & 0x7f;
2679       value >>= 7;
2680       if (value)
2681         byte |= 0x80;
2682       VEC_safe_push (uchar, gc, *data_area, byte);
2683     }
2684   while (value);
2685 }
2686
2687 static void
2688 push_sleb128 (VEC (uchar, gc) **data_area, int value)
2689 {
2690   unsigned char byte;
2691   int more;
2692
2693   do
2694     {
2695       byte = value & 0x7f;
2696       value >>= 7;
2697       more = ! ((value == 0 && (byte & 0x40) == 0)
2698                 || (value == -1 && (byte & 0x40) != 0));
2699       if (more)
2700         byte |= 0x80;
2701       VEC_safe_push (uchar, gc, *data_area, byte);
2702     }
2703   while (more);
2704 }
2705
2706 \f
2707 #ifndef HAVE_AS_LEB128
2708 static int
2709 dw2_size_of_call_site_table (int section)
2710 {
2711   int n = VEC_length (call_site_record, crtl->eh.call_site_record[section]);
2712   int size = n * (4 + 4 + 4);
2713   int i;
2714
2715   for (i = 0; i < n; ++i)
2716     {
2717       struct call_site_record_d *cs =
2718         VEC_index (call_site_record, crtl->eh.call_site_record[section], i);
2719       size += size_of_uleb128 (cs->action);
2720     }
2721
2722   return size;
2723 }
2724
2725 static int
2726 sjlj_size_of_call_site_table (void)
2727 {
2728   int n = VEC_length (call_site_record, crtl->eh.call_site_record[0]);
2729   int size = 0;
2730   int i;
2731
2732   for (i = 0; i < n; ++i)
2733     {
2734       struct call_site_record_d *cs =
2735         VEC_index (call_site_record, crtl->eh.call_site_record[0], i);
2736       size += size_of_uleb128 (INTVAL (cs->landing_pad));
2737       size += size_of_uleb128 (cs->action);
2738     }
2739
2740   return size;
2741 }
2742 #endif
2743
2744 static void
2745 dw2_output_call_site_table (int cs_format, int section)
2746 {
2747   int n = VEC_length (call_site_record, crtl->eh.call_site_record[section]);
2748   int i;
2749   const char *begin;
2750
2751   if (section == 0)
2752     begin = current_function_func_begin_label;
2753   else if (first_function_block_is_cold)
2754     begin = crtl->subsections.hot_section_label;
2755   else
2756     begin = crtl->subsections.cold_section_label;
2757
2758   for (i = 0; i < n; ++i)
2759     {
2760       struct call_site_record_d *cs =
2761         VEC_index (call_site_record, crtl->eh.call_site_record[section], i);
2762       char reg_start_lab[32];
2763       char reg_end_lab[32];
2764       char landing_pad_lab[32];
2765
2766       ASM_GENERATE_INTERNAL_LABEL (reg_start_lab, "LEHB", call_site_base + i);
2767       ASM_GENERATE_INTERNAL_LABEL (reg_end_lab, "LEHE", call_site_base + i);
2768
2769       if (cs->landing_pad)
2770         ASM_GENERATE_INTERNAL_LABEL (landing_pad_lab, "L",
2771                                      CODE_LABEL_NUMBER (cs->landing_pad));
2772
2773       /* ??? Perhaps use insn length scaling if the assembler supports
2774          generic arithmetic.  */
2775       /* ??? Perhaps use attr_length to choose data1 or data2 instead of
2776          data4 if the function is small enough.  */
2777       if (cs_format == DW_EH_PE_uleb128)
2778         {
2779           dw2_asm_output_delta_uleb128 (reg_start_lab, begin,
2780                                         "region %d start", i);
2781           dw2_asm_output_delta_uleb128 (reg_end_lab, reg_start_lab,
2782                                         "length");
2783           if (cs->landing_pad)
2784             dw2_asm_output_delta_uleb128 (landing_pad_lab, begin,
2785                                           "landing pad");
2786           else
2787             dw2_asm_output_data_uleb128 (0, "landing pad");
2788         }
2789       else
2790         {
2791           dw2_asm_output_delta (4, reg_start_lab, begin,
2792                                 "region %d start", i);
2793           dw2_asm_output_delta (4, reg_end_lab, reg_start_lab, "length");
2794           if (cs->landing_pad)
2795             dw2_asm_output_delta (4, landing_pad_lab, begin,
2796                                   "landing pad");
2797           else
2798             dw2_asm_output_data (4, 0, "landing pad");
2799         }
2800       dw2_asm_output_data_uleb128 (cs->action, "action");
2801     }
2802
2803   call_site_base += n;
2804 }
2805
2806 static void
2807 sjlj_output_call_site_table (void)
2808 {
2809   int n = VEC_length (call_site_record, crtl->eh.call_site_record[0]);
2810   int i;
2811
2812   for (i = 0; i < n; ++i)
2813     {
2814       struct call_site_record_d *cs =
2815         VEC_index (call_site_record, crtl->eh.call_site_record[0], i);
2816
2817       dw2_asm_output_data_uleb128 (INTVAL (cs->landing_pad),
2818                                    "region %d landing pad", i);
2819       dw2_asm_output_data_uleb128 (cs->action, "action");
2820     }
2821
2822   call_site_base += n;
2823 }
2824
2825 /* Switch to the section that should be used for exception tables.  */
2826
2827 static void
2828 switch_to_exception_section (const char * ARG_UNUSED (fnname))
2829 {
2830   section *s;
2831
2832   if (exception_section)
2833     s = exception_section;
2834   else
2835     {
2836       /* Compute the section and cache it into exception_section,
2837          unless it depends on the function name.  */
2838       if (targetm_common.have_named_sections)
2839         {
2840           int flags;
2841
2842           if (EH_TABLES_CAN_BE_READ_ONLY)
2843             {
2844               int tt_format =
2845                 ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/1);
2846               flags = ((! flag_pic
2847                         || ((tt_format & 0x70) != DW_EH_PE_absptr
2848                             && (tt_format & 0x70) != DW_EH_PE_aligned))
2849                        ? 0 : SECTION_WRITE);
2850             }
2851           else
2852             flags = SECTION_WRITE;
2853
2854 #ifdef HAVE_LD_EH_GC_SECTIONS
2855           if (flag_function_sections)
2856             {
2857               char *section_name = XNEWVEC (char, strlen (fnname) + 32);
2858               sprintf (section_name, ".gcc_except_table.%s", fnname);
2859               s = get_section (section_name, flags, NULL);
2860               free (section_name);
2861             }
2862           else
2863 #endif
2864             exception_section
2865               = s = get_section (".gcc_except_table", flags, NULL);
2866         }
2867       else
2868         exception_section
2869           = s = flag_pic ? data_section : readonly_data_section;
2870     }
2871
2872   switch_to_section (s);
2873 }
2874
2875
2876 /* Output a reference from an exception table to the type_info object TYPE.
2877    TT_FORMAT and TT_FORMAT_SIZE describe the DWARF encoding method used for
2878    the value.  */
2879
2880 static void
2881 output_ttype (tree type, int tt_format, int tt_format_size)
2882 {
2883   rtx value;
2884   bool is_public = true;
2885
2886   if (type == NULL_TREE)
2887     value = const0_rtx;
2888   else
2889     {
2890       struct varpool_node *node;
2891
2892       /* FIXME lto.  pass_ipa_free_lang_data changes all types to
2893          runtime types so TYPE should already be a runtime type
2894          reference.  When pass_ipa_free_lang data is made a default
2895          pass, we can then remove the call to lookup_type_for_runtime
2896          below.  */
2897       if (TYPE_P (type))
2898         type = lookup_type_for_runtime (type);
2899
2900       value = expand_expr (type, NULL_RTX, VOIDmode, EXPAND_INITIALIZER);
2901
2902       /* Let cgraph know that the rtti decl is used.  Not all of the
2903          paths below go through assemble_integer, which would take
2904          care of this for us.  */
2905       STRIP_NOPS (type);
2906       if (TREE_CODE (type) == ADDR_EXPR)
2907         {
2908           type = TREE_OPERAND (type, 0);
2909           if (TREE_CODE (type) == VAR_DECL)
2910             {
2911               node = varpool_node (type);
2912               if (node)
2913                 varpool_mark_needed_node (node);
2914               is_public = TREE_PUBLIC (type);
2915             }
2916         }
2917       else
2918         gcc_assert (TREE_CODE (type) == INTEGER_CST);
2919     }
2920
2921   /* Allow the target to override the type table entry format.  */
2922   if (targetm.asm_out.ttype (value))
2923     return;
2924
2925   if (tt_format == DW_EH_PE_absptr || tt_format == DW_EH_PE_aligned)
2926     assemble_integer (value, tt_format_size,
2927                       tt_format_size * BITS_PER_UNIT, 1);
2928   else
2929     dw2_asm_output_encoded_addr_rtx (tt_format, value, is_public, NULL);
2930 }
2931
2932 static void
2933 output_one_function_exception_table (int section)
2934 {
2935   int tt_format, cs_format, lp_format, i;
2936 #ifdef HAVE_AS_LEB128
2937   char ttype_label[32];
2938   char cs_after_size_label[32];
2939   char cs_end_label[32];
2940 #else
2941   int call_site_len;
2942 #endif
2943   int have_tt_data;
2944   int tt_format_size = 0;
2945
2946   have_tt_data = (VEC_length (tree, cfun->eh->ttype_data)
2947                   || (targetm.arm_eabi_unwinder
2948                       ? VEC_length (tree, cfun->eh->ehspec_data.arm_eabi)
2949                       : VEC_length (uchar, cfun->eh->ehspec_data.other)));
2950
2951   /* Indicate the format of the @TType entries.  */
2952   if (! have_tt_data)
2953     tt_format = DW_EH_PE_omit;
2954   else
2955     {
2956       tt_format = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/1);
2957 #ifdef HAVE_AS_LEB128
2958       ASM_GENERATE_INTERNAL_LABEL (ttype_label,
2959                                    section ? "LLSDATTC" : "LLSDATT",
2960                                    current_function_funcdef_no);
2961 #endif
2962       tt_format_size = size_of_encoded_value (tt_format);
2963
2964       assemble_align (tt_format_size * BITS_PER_UNIT);
2965     }
2966
2967   targetm.asm_out.internal_label (asm_out_file, section ? "LLSDAC" : "LLSDA",
2968                                   current_function_funcdef_no);
2969
2970   /* The LSDA header.  */
2971
2972   /* Indicate the format of the landing pad start pointer.  An omitted
2973      field implies @LPStart == @Start.  */
2974   /* Currently we always put @LPStart == @Start.  This field would
2975      be most useful in moving the landing pads completely out of
2976      line to another section, but it could also be used to minimize
2977      the size of uleb128 landing pad offsets.  */
2978   lp_format = DW_EH_PE_omit;
2979   dw2_asm_output_data (1, lp_format, "@LPStart format (%s)",
2980                        eh_data_format_name (lp_format));
2981
2982   /* @LPStart pointer would go here.  */
2983
2984   dw2_asm_output_data (1, tt_format, "@TType format (%s)",
2985                        eh_data_format_name (tt_format));
2986
2987 #ifndef HAVE_AS_LEB128
2988   if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ)
2989     call_site_len = sjlj_size_of_call_site_table ();
2990   else
2991     call_site_len = dw2_size_of_call_site_table (section);
2992 #endif
2993
2994   /* A pc-relative 4-byte displacement to the @TType data.  */
2995   if (have_tt_data)
2996     {
2997 #ifdef HAVE_AS_LEB128
2998       char ttype_after_disp_label[32];
2999       ASM_GENERATE_INTERNAL_LABEL (ttype_after_disp_label,
3000                                    section ? "LLSDATTDC" : "LLSDATTD",
3001                                    current_function_funcdef_no);
3002       dw2_asm_output_delta_uleb128 (ttype_label, ttype_after_disp_label,
3003                                     "@TType base offset");
3004       ASM_OUTPUT_LABEL (asm_out_file, ttype_after_disp_label);
3005 #else
3006       /* Ug.  Alignment queers things.  */
3007       unsigned int before_disp, after_disp, last_disp, disp;
3008
3009       before_disp = 1 + 1;
3010       after_disp = (1 + size_of_uleb128 (call_site_len)
3011                     + call_site_len
3012                     + VEC_length (uchar, crtl->eh.action_record_data)
3013                     + (VEC_length (tree, cfun->eh->ttype_data)
3014                        * tt_format_size));
3015
3016       disp = after_disp;
3017       do
3018         {
3019           unsigned int disp_size, pad;
3020
3021           last_disp = disp;
3022           disp_size = size_of_uleb128 (disp);
3023           pad = before_disp + disp_size + after_disp;
3024           if (pad % tt_format_size)
3025             pad = tt_format_size - (pad % tt_format_size);
3026           else
3027             pad = 0;
3028           disp = after_disp + pad;
3029         }
3030       while (disp != last_disp);
3031
3032       dw2_asm_output_data_uleb128 (disp, "@TType base offset");
3033 #endif
3034     }
3035
3036   /* Indicate the format of the call-site offsets.  */
3037 #ifdef HAVE_AS_LEB128
3038   cs_format = DW_EH_PE_uleb128;
3039 #else
3040   cs_format = DW_EH_PE_udata4;
3041 #endif
3042   dw2_asm_output_data (1, cs_format, "call-site format (%s)",
3043                        eh_data_format_name (cs_format));
3044
3045 #ifdef HAVE_AS_LEB128
3046   ASM_GENERATE_INTERNAL_LABEL (cs_after_size_label,
3047                                section ? "LLSDACSBC" : "LLSDACSB",
3048                                current_function_funcdef_no);
3049   ASM_GENERATE_INTERNAL_LABEL (cs_end_label,
3050                                section ? "LLSDACSEC" : "LLSDACSE",
3051                                current_function_funcdef_no);
3052   dw2_asm_output_delta_uleb128 (cs_end_label, cs_after_size_label,
3053                                 "Call-site table length");
3054   ASM_OUTPUT_LABEL (asm_out_file, cs_after_size_label);
3055   if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ)
3056     sjlj_output_call_site_table ();
3057   else
3058     dw2_output_call_site_table (cs_format, section);
3059   ASM_OUTPUT_LABEL (asm_out_file, cs_end_label);
3060 #else
3061   dw2_asm_output_data_uleb128 (call_site_len, "Call-site table length");
3062   if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ)
3063     sjlj_output_call_site_table ();
3064   else
3065     dw2_output_call_site_table (cs_format, section);
3066 #endif
3067
3068   /* ??? Decode and interpret the data for flag_debug_asm.  */
3069   {
3070     uchar uc;
3071     FOR_EACH_VEC_ELT (uchar, crtl->eh.action_record_data, i, uc)
3072       dw2_asm_output_data (1, uc, i ? NULL : "Action record table");
3073   }
3074
3075   if (have_tt_data)
3076     assemble_align (tt_format_size * BITS_PER_UNIT);
3077
3078   i = VEC_length (tree, cfun->eh->ttype_data);
3079   while (i-- > 0)
3080     {
3081       tree type = VEC_index (tree, cfun->eh->ttype_data, i);
3082       output_ttype (type, tt_format, tt_format_size);
3083     }
3084
3085 #ifdef HAVE_AS_LEB128
3086   if (have_tt_data)
3087       ASM_OUTPUT_LABEL (asm_out_file, ttype_label);
3088 #endif
3089
3090   /* ??? Decode and interpret the data for flag_debug_asm.  */
3091   if (targetm.arm_eabi_unwinder)
3092     {
3093       tree type;
3094       for (i = 0;
3095            VEC_iterate (tree, cfun->eh->ehspec_data.arm_eabi, i, type); ++i)
3096         output_ttype (type, tt_format, tt_format_size);
3097     }
3098   else
3099     {
3100       uchar uc;
3101       for (i = 0;
3102            VEC_iterate (uchar, cfun->eh->ehspec_data.other, i, uc); ++i)
3103         dw2_asm_output_data (1, uc,
3104                              i ? NULL : "Exception specification table");
3105     }
3106 }
3107
3108 void
3109 output_function_exception_table (const char *fnname)
3110 {
3111   rtx personality = get_personality_function (current_function_decl);
3112
3113   /* Not all functions need anything.  */
3114   if (! crtl->uses_eh_lsda)
3115     return;
3116
3117   if (personality)
3118     {
3119       assemble_external_libcall (personality);
3120
3121       if (targetm.asm_out.emit_except_personality)
3122         targetm.asm_out.emit_except_personality (personality);
3123     }
3124
3125   switch_to_exception_section (fnname);
3126
3127   /* If the target wants a label to begin the table, emit it here.  */
3128   targetm.asm_out.emit_except_table_label (asm_out_file);
3129
3130   output_one_function_exception_table (0);
3131   if (crtl->eh.call_site_record[1] != NULL)
3132     output_one_function_exception_table (1);
3133
3134   switch_to_section (current_function_section ());
3135 }
3136
3137 void
3138 set_eh_throw_stmt_table (struct function *fun, struct htab *table)
3139 {
3140   fun->eh->throw_stmt_table = table;
3141 }
3142
3143 htab_t
3144 get_eh_throw_stmt_table (struct function *fun)
3145 {
3146   return fun->eh->throw_stmt_table;
3147 }
3148 \f
3149 /* Determine if the function needs an EH personality function.  */
3150
3151 enum eh_personality_kind
3152 function_needs_eh_personality (struct function *fn)
3153 {
3154   enum eh_personality_kind kind = eh_personality_none;
3155   eh_region i;
3156
3157   FOR_ALL_EH_REGION_FN (i, fn)
3158     {
3159       switch (i->type)
3160         {
3161         case ERT_CLEANUP:
3162           /* Can do with any personality including the generic C one.  */
3163           kind = eh_personality_any;
3164           break;
3165
3166         case ERT_TRY:
3167         case ERT_ALLOWED_EXCEPTIONS:
3168           /* Always needs a EH personality function.  The generic C
3169              personality doesn't handle these even for empty type lists.  */
3170           return eh_personality_lang;
3171
3172         case ERT_MUST_NOT_THROW:
3173           /* Always needs a EH personality function.  The language may specify
3174              what abort routine that must be used, e.g. std::terminate.  */
3175           return eh_personality_lang;
3176         }
3177     }
3178
3179   return kind;
3180 }
3181 \f
3182 /* Dump EH information to OUT.  */
3183
3184 void
3185 dump_eh_tree (FILE * out, struct function *fun)
3186 {
3187   eh_region i;
3188   int depth = 0;
3189   static const char *const type_name[] = {
3190     "cleanup", "try", "allowed_exceptions", "must_not_throw"
3191   };
3192
3193   i = fun->eh->region_tree;
3194   if (!i)
3195     return;
3196
3197   fprintf (out, "Eh tree:\n");
3198   while (1)
3199     {
3200       fprintf (out, "  %*s %i %s", depth * 2, "",
3201                i->index, type_name[(int) i->type]);
3202
3203       if (i->landing_pads)
3204         {
3205           eh_landing_pad lp;
3206
3207           fprintf (out, " land:");
3208           if (current_ir_type () == IR_GIMPLE)
3209             {
3210               for (lp = i->landing_pads; lp ; lp = lp->next_lp)
3211                 {
3212                   fprintf (out, "{%i,", lp->index);
3213                   print_generic_expr (out, lp->post_landing_pad, 0);
3214                   fputc ('}', out);
3215                   if (lp->next_lp)
3216                     fputc (',', out);
3217                 }
3218             }
3219           else
3220             {
3221               for (lp = i->landing_pads; lp ; lp = lp->next_lp)
3222                 {
3223                   fprintf (out, "{%i,", lp->index);
3224                   if (lp->landing_pad)
3225                     fprintf (out, "%i%s,", INSN_UID (lp->landing_pad),
3226                              NOTE_P (lp->landing_pad) ? "(del)" : "");
3227                   else
3228                     fprintf (out, "(nil),");
3229                   if (lp->post_landing_pad)
3230                     {
3231                       rtx lab = label_rtx (lp->post_landing_pad);
3232                       fprintf (out, "%i%s}", INSN_UID (lab),
3233                                NOTE_P (lab) ? "(del)" : "");
3234                     }
3235                   else
3236                     fprintf (out, "(nil)}");
3237                   if (lp->next_lp)
3238                     fputc (',', out);
3239                 }
3240             }
3241         }
3242
3243       switch (i->type)
3244         {
3245         case ERT_CLEANUP:
3246         case ERT_MUST_NOT_THROW:
3247           break;
3248
3249         case ERT_TRY:
3250           {
3251             eh_catch c;
3252             fprintf (out, " catch:");
3253             for (c = i->u.eh_try.first_catch; c; c = c->next_catch)
3254               {
3255                 fputc ('{', out);
3256                 if (c->label)
3257                   {
3258                     fprintf (out, "lab:");
3259                     print_generic_expr (out, c->label, 0);
3260                     fputc (';', out);
3261                   }
3262                 print_generic_expr (out, c->type_list, 0);
3263                 fputc ('}', out);
3264                 if (c->next_catch)
3265                   fputc (',', out);
3266               }
3267           }
3268           break;
3269
3270         case ERT_ALLOWED_EXCEPTIONS:
3271           fprintf (out, " filter :%i types:", i->u.allowed.filter);
3272           print_generic_expr (out, i->u.allowed.type_list, 0);
3273           break;
3274         }
3275       fputc ('\n', out);
3276
3277       /* If there are sub-regions, process them.  */
3278       if (i->inner)
3279         i = i->inner, depth++;
3280       /* If there are peers, process them.  */
3281       else if (i->next_peer)
3282         i = i->next_peer;
3283       /* Otherwise, step back up the tree to the next peer.  */
3284       else
3285         {
3286           do
3287             {
3288               i = i->outer;
3289               depth--;
3290               if (i == NULL)
3291                 return;
3292             }
3293           while (i->next_peer == NULL);
3294           i = i->next_peer;
3295         }
3296     }
3297 }
3298
3299 /* Dump the EH tree for FN on stderr.  */
3300
3301 DEBUG_FUNCTION void
3302 debug_eh_tree (struct function *fn)
3303 {
3304   dump_eh_tree (stderr, fn);
3305 }
3306
3307 /* Verify invariants on EH datastructures.  */
3308
3309 DEBUG_FUNCTION void
3310 verify_eh_tree (struct function *fun)
3311 {
3312   eh_region r, outer;
3313   int nvisited_lp, nvisited_r;
3314   int count_lp, count_r, depth, i;
3315   eh_landing_pad lp;
3316   bool err = false;
3317
3318   if (!fun->eh->region_tree)
3319     return;
3320
3321   count_r = 0;
3322   for (i = 1; VEC_iterate (eh_region, fun->eh->region_array, i, r); ++i)
3323     if (r)
3324       {
3325         if (r->index == i)
3326           count_r++;
3327         else
3328           {
3329             error ("region_array is corrupted for region %i", r->index);
3330             err = true;
3331           }
3332       }
3333
3334   count_lp = 0;
3335   for (i = 1; VEC_iterate (eh_landing_pad, fun->eh->lp_array, i, lp); ++i)
3336     if (lp)
3337       {
3338         if (lp->index == i)
3339           count_lp++;
3340         else
3341           {
3342             error ("lp_array is corrupted for lp %i", lp->index);
3343             err = true;
3344           }
3345       }
3346
3347   depth = nvisited_lp = nvisited_r = 0;
3348   outer = NULL;
3349   r = fun->eh->region_tree;
3350   while (1)
3351     {
3352       if (VEC_index (eh_region, fun->eh->region_array, r->index) != r)
3353         {
3354           error ("region_array is corrupted for region %i", r->index);
3355           err = true;
3356         }
3357       if (r->outer != outer)
3358         {
3359           error ("outer block of region %i is wrong", r->index);
3360           err = true;
3361         }
3362       if (depth < 0)
3363         {
3364           error ("negative nesting depth of region %i", r->index);
3365           err = true;
3366         }
3367       nvisited_r++;
3368
3369       for (lp = r->landing_pads; lp ; lp = lp->next_lp)
3370         {
3371           if (VEC_index (eh_landing_pad, fun->eh->lp_array, lp->index) != lp)
3372             {
3373               error ("lp_array is corrupted for lp %i", lp->index);
3374               err = true;
3375             }
3376           if (lp->region != r)
3377             {
3378               error ("region of lp %i is wrong", lp->index);
3379               err = true;
3380             }
3381           nvisited_lp++;
3382         }
3383
3384       if (r->inner)
3385         outer = r, r = r->inner, depth++;
3386       else if (r->next_peer)
3387         r = r->next_peer;
3388       else
3389         {
3390           do
3391             {
3392               r = r->outer;
3393               if (r == NULL)
3394                 goto region_done;
3395               depth--;
3396               outer = r->outer;
3397             }
3398           while (r->next_peer == NULL);
3399           r = r->next_peer;
3400         }
3401     }
3402  region_done:
3403   if (depth != 0)
3404     {
3405       error ("tree list ends on depth %i", depth);
3406       err = true;
3407     }
3408   if (count_r != nvisited_r)
3409     {
3410       error ("region_array does not match region_tree");
3411       err = true;
3412     }
3413   if (count_lp != nvisited_lp)
3414     {
3415       error ("lp_array does not match region_tree");
3416       err = true;
3417     }
3418
3419   if (err)
3420     {
3421       dump_eh_tree (stderr, fun);
3422       internal_error ("verify_eh_tree failed");
3423     }
3424 }
3425 \f
3426 #include "gt-except.h"