OSDN Git Service

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