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