OSDN Git Service

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