OSDN Git Service

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