OSDN Git Service

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