OSDN Git Service

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